diff --git a/src/xenia/cpu/libjit/libjit_emit_alu.cc b/src/xenia/cpu/libjit/libjit_emit_alu.cc index 170be5769..08c2a6e26 100644 --- a/src/xenia/cpu/libjit/libjit_emit_alu.cc +++ b/src/xenia/cpu/libjit/libjit_emit_alu.cc @@ -29,10 +29,10 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // // This is a different codepath as we need to use llvm.sadd.with.overflow. // // Function* sadd_with_overflow = Intrinsic::getDeclaration( -// e.gen_module(), Intrinsic::sadd_with_overflow, b.getInt64Ty()); -// Value* v = b.CreateCall2(sadd_with_overflow, +// e.gen_module(), Intrinsic::sadd_with_overflow, jit_type_nint); +// jit_value_t v = b.CreateCall2(sadd_with_overflow, // e.gpr_value(i.XO.RA), e.gpr_value(i.XO.RB)); -// Value* v0 = b.CreateExtractValue(v, 0); +// jit_value_t v0 = b.CreateExtractValue(v, 0); // e.update_gpr_value(i.XO.RT, v0); // e.update_xer_with_overflow(b.CreateExtractValue(v, 1)); // @@ -44,7 +44,7 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // return 0; // } else { // // No OE bit setting. -// Value* v = b.CreateAdd(e.gpr_value(i.XO.RA), e.gpr_value(i.XO.RB)); +// jit_value_t v = b.CreateAdd(e.gpr_value(i.XO.RA), e.gpr_value(i.XO.RB)); // e.update_gpr_value(i.XO.RT, v); // // if (i.XO.Rc) { @@ -73,7 +73,7 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // // else // // RT <- (RA) + EXTS(SI) // -// Value* v = b.getInt64(XEEXTS16(i.D.DS)); +// jit_value_t v = b.getInt64(XEEXTS16(i.D.DS)); // if (i.D.RA) { // v = b.CreateAdd(e.gpr_value(i.D.RA), v); // } @@ -86,8 +86,8 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // // RT <- (RA) + EXTS(SI) // // Function* sadd_with_overflow = Intrinsic::getDeclaration( -// e.gen_module(), Intrinsic::sadd_with_overflow, b.getInt64Ty()); -// Value* v = b.CreateCall2(sadd_with_overflow, +// e.gen_module(), Intrinsic::sadd_with_overflow, jit_type_nint); +// jit_value_t v = b.CreateCall2(sadd_with_overflow, // e.gpr_value(i.D.RA), b.getInt64(XEEXTS16(i.D.DS))); // e.update_gpr_value(i.D.RT, b.CreateExtractValue(v, 0)); // e.update_xer_with_carry(b.CreateExtractValue(v, 1)); @@ -106,7 +106,7 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // // else // // RT <- (RA) + EXTS(SI) || i16.0 // -// Value* v = b.getInt64(XEEXTS16(i.D.DS) << 16); +// jit_value_t v = b.getInt64(XEEXTS16(i.D.DS) << 16); // if (i.D.RA) { // v = b.CreateAdd(e.gpr_value(i.D.RA), v); // } @@ -124,11 +124,11 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // // RT <- (RA) + CA // // Function* sadd_with_overflow = Intrinsic::getDeclaration( -// e.gen_module(), Intrinsic::sadd_with_overflow, b.getInt64Ty()); -// Value* ca = b.CreateAnd(b.CreateLShr(e.xer_value(), 29), 0x1); -// Value* v = b.CreateCall2(sadd_with_overflow, +// e.gen_module(), Intrinsic::sadd_with_overflow, jit_type_nint); +// jit_value_t ca = b.CreateAnd(b.CreateLShr(e.xer_value(), 29), 0x1); +// jit_value_t v = b.CreateCall2(sadd_with_overflow, // e.gpr_value(i.XO.RA), ca); -// Value* add_value = b.CreateExtractValue(v, 0); +// jit_value_t add_value = b.CreateExtractValue(v, 0); // e.update_gpr_value(i.XO.RT, add_value); // if (i.XO.OE) { // // With XER[SO] update too. @@ -166,8 +166,8 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // // RT[32:63] <- dividend ÷ divisor // // RT[0:31] <- undefined // -// Value* dividend = b.CreateTrunc(e.gpr_value(i.XO.RA), b.getInt32Ty()); -// Value* divisor = b.CreateTrunc(e.gpr_value(i.XO.RB), b.getInt32Ty()); +// jit_value_t dividend = b.CreateTrunc(e.gpr_value(i.XO.RA), b.getInt32Ty()); +// jit_value_t divisor = b.CreateTrunc(e.gpr_value(i.XO.RB), b.getInt32Ty()); // // // Note that we skip the zero handling block and just avoid the divide if // // we are OE=0. @@ -187,8 +187,8 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // // // Divide. // b.SetInsertPoint(nonzero_bb); -// Value* v = b.CreateSDiv(dividend, divisor); -// v = b.CreateSExt(v, b.getInt64Ty()); +// jit_value_t v = b.CreateSDiv(dividend, divisor); +// v = b.CreateSExt(v, jit_type_nint); // e.update_gpr_value(i.XO.RT, v); // // // If we are OE=1 we need to clear the overflow bit. @@ -219,8 +219,8 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // // RT[32:63] <- dividend ÷ divisor // // RT[0:31] <- undefined // -// Value* dividend = b.CreateTrunc(e.gpr_value(i.XO.RA), b.getInt32Ty()); -// Value* divisor = b.CreateTrunc(e.gpr_value(i.XO.RB), b.getInt32Ty()); +// jit_value_t dividend = b.CreateTrunc(e.gpr_value(i.XO.RA), b.getInt32Ty()); +// jit_value_t divisor = b.CreateTrunc(e.gpr_value(i.XO.RB), b.getInt32Ty()); // // // Note that we skip the zero handling block and just avoid the divide if // // we are OE=0. @@ -240,8 +240,8 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // // // Divide. // b.SetInsertPoint(nonzero_bb); -// Value* v = b.CreateUDiv(dividend, divisor); -// v = b.CreateZExt(v, b.getInt64Ty()); +// jit_value_t v = b.CreateUDiv(dividend, divisor); +// v = b.CreateZExt(v, jit_type_nint); // e.update_gpr_value(i.XO.RT, v); // // // If we are OE=1 we need to clear the overflow bit. @@ -295,8 +295,8 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // // overflows. It should be truncating the result, but I'm not sure what LLVM // // does. // -// Value* v = b.CreateMul(e.gpr_value(i.D.RA), b.getInt64(XEEXTS16(i.D.DS))); -// e.update_gpr_value(i.D.RT, b.CreateTrunc(v, b.getInt64Ty())); +// jit_value_t v = b.CreateMul(e.gpr_value(i.D.RA), b.getInt64(XEEXTS16(i.D.DS))); +// e.update_gpr_value(i.D.RT, b.CreateTrunc(v, jit_type_nint)); // // return 0; //} @@ -310,8 +310,8 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // return 1; // } // -// Value* v = b.CreateMul(b.CreateSExt(e.gpr_value(i.XO.RA), b.getInt64Ty()), -// b.CreateSExt(e.gpr_value(i.XO.RB), b.getInt64Ty())); +// jit_value_t v = b.CreateMul(b.CreateSExt(e.gpr_value(i.XO.RA), jit_type_nint), +// b.CreateSExt(e.gpr_value(i.XO.RB), jit_type_nint)); // e.update_gpr_value(i.XO.RT, v); // // if (i.XO.Rc) { @@ -333,10 +333,10 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // // This may just magically do that... // // Function* ssub_with_overflow = Intrinsic::getDeclaration( -// e.gen_module(), Intrinsic::ssub_with_overflow, b.getInt64Ty()); -// Value* v = b.CreateCall2(ssub_with_overflow, +// e.gen_module(), Intrinsic::ssub_with_overflow, jit_type_nint); +// jit_value_t v = b.CreateCall2(ssub_with_overflow, // b.getInt64(0), e.gpr_value(i.XO.RA)); -// Value* v0 = b.CreateExtractValue(v, 0); +// jit_value_t v0 = b.CreateExtractValue(v, 0); // e.update_gpr_value(i.XO.RT, v0); // e.update_xer_with_overflow(b.CreateExtractValue(v, 1)); // @@ -348,7 +348,7 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // return 0; // } else { // // No OE bit setting. -// Value* v = b.CreateSub(b.getInt64(0), e.gpr_value(i.XO.RA)); +// jit_value_t v = b.CreateSub(b.getInt64(0), e.gpr_value(i.XO.RA)); // e.update_gpr_value(i.XO.RT, v); // // if (i.XO.Rc) { @@ -368,10 +368,10 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // // This is a different codepath as we need to use llvm.ssub.with.overflow. // // Function* ssub_with_overflow = Intrinsic::getDeclaration( -// e.gen_module(), Intrinsic::ssub_with_overflow, b.getInt64Ty()); -// Value* v = b.CreateCall2(ssub_with_overflow, +// e.gen_module(), Intrinsic::ssub_with_overflow, jit_type_nint); +// jit_value_t v = b.CreateCall2(ssub_with_overflow, // e.gpr_value(i.XO.RB), e.gpr_value(i.XO.RA)); -// Value* v0 = b.CreateExtractValue(v, 0); +// jit_value_t v0 = b.CreateExtractValue(v, 0); // e.update_gpr_value(i.XO.RT, v0); // e.update_xer_with_overflow(b.CreateExtractValue(v, 1)); // @@ -383,7 +383,7 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // return 0; // } else { // // No OE bit setting. -// Value* v = b.CreateSub(e.gpr_value(i.XO.RB), e.gpr_value(i.XO.RA)); +// jit_value_t v = b.CreateSub(e.gpr_value(i.XO.RB), e.gpr_value(i.XO.RA)); // e.update_gpr_value(i.XO.RT, v); // // if (i.XO.Rc) { @@ -404,8 +404,8 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // // RT <- ¬(RA) + EXTS(SI) + 1 // // Function* ssub_with_overflow = Intrinsic::getDeclaration( -// e.gen_module(), Intrinsic::ssub_with_overflow, b.getInt64Ty()); -// Value* v = b.CreateCall2(ssub_with_overflow, +// e.gen_module(), Intrinsic::ssub_with_overflow, jit_type_nint); +// jit_value_t v = b.CreateCall2(ssub_with_overflow, // b.getInt64(XEEXTS16(i.D.DS)), e.gpr_value(i.D.RA)); // e.update_gpr_value(i.D.RT, b.CreateExtractValue(v, 0)); // e.update_xer_with_carry(b.CreateExtractValue(v, 1)); @@ -419,13 +419,13 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // // TODO(benvanik): possible that the add of rb+ca needs to also check for // // overflow! // -// Value* ca = b.CreateAnd(b.CreateLShr(e.xer_value(), 29), 0x1); +// jit_value_t ca = b.CreateAnd(b.CreateLShr(e.xer_value(), 29), 0x1); // Function* uadd_with_overflow = Intrinsic::getDeclaration( -// e.gen_module(), Intrinsic::uadd_with_overflow, b.getInt64Ty()); -// Value* v = b.CreateCall2(uadd_with_overflow, +// e.gen_module(), Intrinsic::uadd_with_overflow, jit_type_nint); +// jit_value_t v = b.CreateCall2(uadd_with_overflow, // b.CreateNeg(e.gpr_value(i.XO.RA)), // b.CreateAdd(e.gpr_value(i.XO.RB), ca)); -// Value* v0 = b.CreateExtractValue(v, 0); +// jit_value_t v0 = b.CreateExtractValue(v, 0); // e.update_gpr_value(i.XO.RT, v0); // // if (i.XO.OE) { @@ -474,14 +474,14 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // uint32_t BF = i.X.RT >> 2; // uint32_t L = i.X.RT & 1; // -// Value* lhs = e.gpr_value(i.X.RA); -// Value* rhs = e.gpr_value(i.X.RB); +// jit_value_t lhs = e.gpr_value(i.X.RA); +// jit_value_t rhs = e.gpr_value(i.X.RB); // if (!L) { // // 32-bit - truncate and sign extend. // lhs = b.CreateTrunc(lhs, b.getInt32Ty()); -// lhs = b.CreateSExt(lhs, b.getInt64Ty()); +// lhs = b.CreateSExt(lhs, jit_type_nint); // rhs = b.CreateTrunc(rhs, b.getInt32Ty()); -// rhs = b.CreateSExt(rhs, b.getInt64Ty()); +// rhs = b.CreateSExt(rhs, jit_type_nint); // } // // e.update_cr_with_cond(BF, lhs, rhs, true); @@ -505,14 +505,14 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // uint32_t BF = i.D.RT >> 2; // uint32_t L = i.D.RT & 1; // -// Value* lhs = e.gpr_value(i.D.RA); +// jit_value_t lhs = e.gpr_value(i.D.RA); // if (!L) { // // 32-bit - truncate and sign extend. // lhs = b.CreateTrunc(lhs, b.getInt32Ty()); -// lhs = b.CreateSExt(lhs, b.getInt64Ty()); +// lhs = b.CreateSExt(lhs, jit_type_nint); // } // -// Value* rhs = b.getInt64(XEEXTS16(i.D.DS)); +// jit_value_t rhs = b.getInt64(XEEXTS16(i.D.DS)); // e.update_cr_with_cond(BF, lhs, rhs, true); // // return 0; @@ -536,14 +536,14 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // uint32_t BF = i.X.RT >> 2; // uint32_t L = i.X.RT & 1; // -// Value* lhs = e.gpr_value(i.X.RA); -// Value* rhs = e.gpr_value(i.X.RB); +// jit_value_t lhs = e.gpr_value(i.X.RA); +// jit_value_t rhs = e.gpr_value(i.X.RB); // if (!L) { // // 32-bit - truncate and zero extend. // lhs = b.CreateTrunc(lhs, b.getInt32Ty()); -// lhs = b.CreateZExt(lhs, b.getInt64Ty()); +// lhs = b.CreateZExt(lhs, jit_type_nint); // rhs = b.CreateTrunc(rhs, b.getInt32Ty()); -// rhs = b.CreateZExt(rhs, b.getInt64Ty()); +// rhs = b.CreateZExt(rhs, jit_type_nint); // } // // e.update_cr_with_cond(BF, lhs, rhs, false); @@ -567,14 +567,14 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // uint32_t BF = i.D.RT >> 2; // uint32_t L = i.D.RT & 1; // -// Value* lhs = e.gpr_value(i.D.RA); +// jit_value_t lhs = e.gpr_value(i.D.RA); // if (!L) { // // 32-bit - truncate and zero extend. // lhs = b.CreateTrunc(lhs, b.getInt32Ty()); -// lhs = b.CreateZExt(lhs, b.getInt64Ty()); +// lhs = b.CreateZExt(lhs, jit_type_nint); // } // -// Value* rhs = b.getInt64(i.D.DS); +// jit_value_t rhs = b.getInt64(i.D.DS); // e.update_cr_with_cond(BF, lhs, rhs, false); // // return 0; @@ -586,7 +586,7 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins //XEEMITTER(andx, 0x7C000038, X )(LibjitEmitter& e, jit_function_t f, InstrData& i) { // // RA <- (RS) & (RB) // -// Value* v = b.CreateAnd(e.gpr_value(i.X.RT), e.gpr_value(i.X.RB)); +// jit_value_t v = b.CreateAnd(e.gpr_value(i.X.RT), e.gpr_value(i.X.RB)); // e.update_gpr_value(i.X.RA, v); // // if (i.X.Rc) { @@ -600,7 +600,7 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins //XEEMITTER(andcx, 0x7C000078, X )(LibjitEmitter& e, jit_function_t f, InstrData& i) { // // RA <- (RS) & ¬(RB) // -// Value* v = b.CreateXor(e.gpr_value(i.X.RB), -1); +// jit_value_t v = b.CreateXor(e.gpr_value(i.X.RB), -1); // v = b.CreateAnd(e.gpr_value(i.X.RT), v); // e.update_gpr_value(i.X.RA, v); // @@ -615,7 +615,7 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins //XEEMITTER(andix, 0x70000000, D )(LibjitEmitter& e, jit_function_t f, InstrData& i) { // // RA <- (RS) & (i48.0 || UI) // -// Value* v = b.CreateAnd(e.gpr_value(i.D.RT), (uint64_t)i.D.DS); +// jit_value_t v = b.CreateAnd(e.gpr_value(i.D.RT), (uint64_t)i.D.DS); // e.update_gpr_value(i.D.RA, v); // // // With cr0 update. @@ -627,7 +627,7 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins //XEEMITTER(andisx, 0x74000000, D )(LibjitEmitter& e, jit_function_t f, InstrData& i) { // // RA <- (RS) & (i32.0 || UI || i16.0) // -// Value* v = b.CreateAnd(e.gpr_value(i.D.RT), ((uint64_t)i.D.DS) << 16); +// jit_value_t v = b.CreateAnd(e.gpr_value(i.D.RT), ((uint64_t)i.D.DS) << 16); // e.update_gpr_value(i.D.RA, v); // // // With cr0 update. @@ -648,16 +648,16 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // // n <- n + 1 // // RA <- n - 32 // -// Value* v = e.gpr_value(i.X.RT); +// jit_value_t v = e.gpr_value(i.X.RT); // v = b.CreateTrunc(v, b.getInt32Ty()); // // std::vector arg_types; // arg_types.push_back(b.getInt32Ty()); // Function* ctlz = Intrinsic::getDeclaration( // e.fn()->getParent(), Intrinsic::ctlz, arg_types); -// Value* count = b.CreateCall2(ctlz, v, b.getInt1(1)); +// jit_value_t count = b.CreateCall2(ctlz, v, b.getInt1(1)); // -// count = b.CreateZExt(count, b.getInt64Ty()); +// count = b.CreateZExt(count, jit_type_nint); // e.update_gpr_value(i.X.RA, count); // // if (i.X.Rc) { @@ -678,9 +678,9 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // // RA[56:63] <- (RS)[56:63] // // RA[0:55] <- i56.s // -// Value* v = e.gpr_value(i.X.RT); -// v = b.CreateTrunc(v, b.getInt8Ty()); -// v = b.CreateSExt(v, b.getInt64Ty()); +// jit_value_t v = e.gpr_value(i.X.RT); +// v = b.CreateTrunc(v, jit_type_ubyte); +// v = b.CreateSExt(v, jit_type_nint); // e.update_gpr_value(i.X.RA, v); // // if (i.X.Rc) { @@ -709,7 +709,7 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins //XEEMITTER(norx, 0x7C0000F8, X )(LibjitEmitter& e, jit_function_t f, InstrData& i) { // // RA <- ¬((RS) | (RB)) // -// Value* v = b.CreateOr(e.gpr_value(i.X.RT), e.gpr_value(i.X.RB)); +// jit_value_t v = b.CreateOr(e.gpr_value(i.X.RT), e.gpr_value(i.X.RB)); // v = b.CreateXor(v, -1); // e.update_gpr_value(i.X.RA, v); // @@ -724,7 +724,7 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins //XEEMITTER(orx, 0x7C000378, X )(LibjitEmitter& e, jit_function_t f, InstrData& i) { // // RA <- (RS) | (RB) // -// Value* v = b.CreateOr(e.gpr_value(i.X.RT), e.gpr_value(i.X.RB)); +// jit_value_t v = b.CreateOr(e.gpr_value(i.X.RT), e.gpr_value(i.X.RB)); // e.update_gpr_value(i.X.RA, v); // // if (i.X.Rc) { @@ -743,7 +743,7 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins //XEEMITTER(ori, 0x60000000, D )(LibjitEmitter& e, jit_function_t f, InstrData& i) { // // RA <- (RS) | (i48.0 || UI) // -// Value* v = b.CreateOr(e.gpr_value(i.D.RT), (uint64_t)i.D.DS); +// jit_value_t v = b.CreateOr(e.gpr_value(i.D.RT), (uint64_t)i.D.DS); // e.update_gpr_value(i.D.RA, v); // // return 0; @@ -752,7 +752,7 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins //XEEMITTER(oris, 0x64000000, D )(LibjitEmitter& e, jit_function_t f, InstrData& i) { // // RA <- (RS) | (i32.0 || UI || i16.0) // -// Value* v = b.CreateOr(e.gpr_value(i.D.RT), ((uint64_t)i.D.DS) << 16); +// jit_value_t v = b.CreateOr(e.gpr_value(i.D.RT), ((uint64_t)i.D.DS) << 16); // e.update_gpr_value(i.D.RA, v); // // return 0; @@ -761,7 +761,7 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins //XEEMITTER(xorx, 0x7C000278, X )(LibjitEmitter& e, jit_function_t f, InstrData& i) { // // RA <- (RS) XOR (RB) // -// Value* v = b.CreateXor(e.gpr_value(i.X.RT), e.gpr_value(i.X.RB)); +// jit_value_t v = b.CreateXor(e.gpr_value(i.X.RT), e.gpr_value(i.X.RB)); // e.update_gpr_value(i.X.RA, v); // // if (i.X.Rc) { @@ -775,7 +775,7 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins //XEEMITTER(xori, 0x68000000, D )(LibjitEmitter& e, jit_function_t f, InstrData& i) { // // RA <- (RS) XOR (i48.0 || UI) // -// Value* v = b.CreateXor(e.gpr_value(i.D.RT), (uint64_t)i.D.DS); +// jit_value_t v = b.CreateXor(e.gpr_value(i.D.RT), (uint64_t)i.D.DS); // e.update_gpr_value(i.D.RA, v); // // return 0; @@ -784,7 +784,7 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins //XEEMITTER(xoris, 0x6C000000, D )(LibjitEmitter& e, jit_function_t f, InstrData& i) { // // RA <- (RS) XOR (i32.0 || UI || i16.0) // -// Value* v = b.CreateXor(e.gpr_value(i.D.RT), ((uint64_t)i.D.DS) << 16); +// jit_value_t v = b.CreateXor(e.gpr_value(i.D.RT), ((uint64_t)i.D.DS) << 16); // e.update_gpr_value(i.D.RA, v); // // return 0; @@ -818,7 +818,7 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // // uint32_t sh = (i.MD.SH5 << 5) | i.MD.SH; // // uint32_t mb = (i.MD.MB5 << 5) | i.MD.MB; // -// // Value* v = e.gpr_value(i.MD.RS); +// // jit_value_t v = e.gpr_value(i.MD.RS); // // if (sh) { // // v = // rotate by sh // // } @@ -853,7 +853,7 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // // RA <- r&m | (RA)&¬m // // // ROTL32(x, y) = rotl(i64.(x||x), y) -// Value* v = b.CreateAnd(e.gpr_value(i.M.RT), UINT32_MAX); +// jit_value_t v = b.CreateAnd(e.gpr_value(i.M.RT), UINT32_MAX); // v = b.CreateOr(b.CreateShl(v, 32), v); // // (v << shift) | (v >> (32 - shift)); // v = b.CreateOr(b.CreateShl(v, i.M.SH), b.CreateLShr(v, 32 - i.M.SH)); @@ -880,10 +880,10 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // // Which seems to just select some bits and set cr0 for use with a branch. // // We can detect this and do less work. // if (!i.M.SH) { -// Value* v = b.CreateAnd( +// jit_value_t v = b.CreateAnd( // b.CreateTrunc(e.gpr_value(i.M.RT), b.getInt32Ty()), // b.getInt32((uint32_t)XEMASK(i.M.MB + 32, i.M.ME + 32))); -// v = b.CreateZExt(v, b.getInt64Ty()); +// v = b.CreateZExt(v, jit_type_nint); // e.update_gpr_value(i.M.RA, v); // if (i.M.Rc) { // // With cr0 update. @@ -893,7 +893,7 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // } // // // ROTL32(x, y) = rotl(i64.(x||x), y) -// Value* v = b.CreateAnd(e.gpr_value(i.M.RT), UINT32_MAX); +// jit_value_t v = b.CreateAnd(e.gpr_value(i.M.RT), UINT32_MAX); // v = b.CreateOr(b.CreateShl(v, 32), v); // // (v << shift) | (v >> (32 - shift)); // v = b.CreateOr(b.CreateShl(v, i.M.SH), b.CreateLShr(v, 32 - i.M.SH)); @@ -930,7 +930,7 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // // m <- i64.0 // // RA <- r & m // -// Value* v = b.CreateShl(e.gpr_value(i.X.RT), e.gpr_value(i.X.RB)); +// jit_value_t v = b.CreateShl(e.gpr_value(i.X.RT), e.gpr_value(i.X.RB)); // v = b.CreateAnd(v, UINT32_MAX); // e.update_gpr_value(i.X.RA, v); // @@ -965,11 +965,11 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // // RA <- r&m | (i64.s)&¬m // // CA <- s & ((r&¬m)[32:63]≠0) // -// Value* rs64 = e.gpr_value(i.X.RT); -// Value* rs32 = b.CreateTrunc(rs64, b.getInt32Ty()); +// jit_value_t rs64 = e.gpr_value(i.X.RT); +// jit_value_t rs32 = b.CreateTrunc(rs64, b.getInt32Ty()); // -// Value* v; -// Value* ca; +// jit_value_t v; +// jit_value_t ca; // if (!i.X.RB) { // // No shift, just a fancy sign extend and CA clearer. // v = rs32; @@ -982,7 +982,7 @@ XEEMITTER(addx, 0x7C000214, XO )(LibjitEmitter& e, jit_function_t f, Ins // ca = b.CreateAnd(b.CreateICmpSLT(v, b.getInt32(0)), // b.CreateICmpSLT(rs64, b.getInt64(0))); // } -// v = b.CreateSExt(v, b.getInt64Ty()); +// v = b.CreateSExt(v, jit_type_nint); // e.update_gpr_value(i.X.RA, v); // e.update_xer_with_carry(ca); // diff --git a/src/xenia/cpu/libjit/libjit_emit_control.cc b/src/xenia/cpu/libjit/libjit_emit_control.cc index fe05fad31..be5bc767a 100644 --- a/src/xenia/cpu/libjit/libjit_emit_control.cc +++ b/src/xenia/cpu/libjit/libjit_emit_control.cc @@ -30,7 +30,7 @@ namespace libjit { // // NOTE: we avoid spilling registers until we know that the target is not // // a basic block within this function. -// Value* target; +// jit_value_t target; // switch (reg) { // case kXEPPCRegLR: // target = e.lr_value(); @@ -51,7 +51,7 @@ namespace libjit { // BasicBlock* next_block = e.GetNextBasicBlock(); // BasicBlock* mismatch_bb = BasicBlock::Create(*e.context(), "lr_mismatch", // e.fn(), next_block); -// Value* lr_cmp = b.CreateICmpEQ(target, ++(e.fn()->arg_begin())); +// jit_value_t lr_cmp = b.CreateICmpEQ(target, ++(e.fn()->arg_begin())); // // The return block will spill registers for us. // b.CreateCondBr(lr_cmp, e.GetReturnBasicBlock(), mismatch_bb); // b.SetInsertPoint(mismatch_bb); @@ -86,7 +86,7 @@ namespace libjit { // XEASSERTNOTNULL(fn_block->outgoing_function); // Function* target_fn = e.GetFunction(fn_block->outgoing_function); // Function::arg_iterator args = e.fn()->arg_begin(); -// Value* state_ptr = args; +// jit_value_t state_ptr = args; // BasicBlock* next_bb = e.GetNextBasicBlock(); // if (!lk || !next_bb) { // // Tail. No need to refill the local register values, just return. @@ -169,12 +169,12 @@ namespace libjit { // e.update_lr_value(b.getInt32(i.address + 4)); // } -// Value* ctr_ok = NULL; +// jit_value_t ctr_ok = NULL; // if (XESELECTBITS(i.B.BO, 2, 2)) { // // Ignore ctr. // } else { // // Decrement counter. -// Value* ctr = e.ctr_value(); +// jit_value_t ctr = e.ctr_value(); // ctr = b.CreateSub(ctr, b.getInt64(1)); // e.update_ctr_value(ctr); @@ -186,11 +186,11 @@ namespace libjit { // } // } -// Value* cond_ok = NULL; +// jit_value_t cond_ok = NULL; // if (XESELECTBITS(i.B.BO, 4, 4)) { // // Ignore cond. // } else { -// Value* cr = e.cr_value(i.B.BI >> 2); +// jit_value_t cr = e.cr_value(i.B.BI >> 2); // cr = b.CreateAnd(cr, 1 << (i.B.BI & 3)); // if (XESELECTBITS(i.B.BO, 3, 3)) { // cond_ok = b.CreateICmpNE(cr, b.getInt64(0)); @@ -200,7 +200,7 @@ namespace libjit { // } // // We do a bit of optimization here to make the llvm assembly easier to read. -// Value* ok = NULL; +// jit_value_t ok = NULL; // if (ctr_ok && cond_ok) { // ok = b.CreateAnd(ctr_ok, cond_ok); // } else if (ctr_ok) { @@ -255,11 +255,11 @@ namespace libjit { // e.update_lr_value(b.getInt32(i.address + 4)); // } -// Value* cond_ok = NULL; +// jit_value_t cond_ok = NULL; // if (XESELECTBITS(i.XL.BO, 4, 4)) { // // Ignore cond. // } else { -// Value* cr = e.cr_value(i.XL.BI >> 2); +// jit_value_t cr = e.cr_value(i.XL.BI >> 2); // cr = b.CreateAnd(cr, 1 << (i.XL.BI & 3)); // if (XESELECTBITS(i.XL.BO, 3, 3)) { // cond_ok = b.CreateICmpNE(cr, b.getInt64(0)); @@ -269,7 +269,7 @@ namespace libjit { // } // // We do a bit of optimization here to make the llvm assembly easier to read. -// Value* ok = NULL; +// jit_value_t ok = NULL; // if (cond_ok) { // ok = cond_ok; // } @@ -318,12 +318,12 @@ namespace libjit { // e.update_lr_value(b.getInt32(i.address + 4)); // } -// Value* ctr_ok = NULL; +// jit_value_t ctr_ok = NULL; // if (XESELECTBITS(i.XL.BO, 2, 2)) { // // Ignore ctr. // } else { // // Decrement counter. -// Value* ctr = e.ctr_value(); +// jit_value_t ctr = e.ctr_value(); // ctr = b.CreateSub(ctr, b.getInt64(1)); // // Ctr check. @@ -334,11 +334,11 @@ namespace libjit { // } // } -// Value* cond_ok = NULL; +// jit_value_t cond_ok = NULL; // if (XESELECTBITS(i.XL.BO, 4, 4)) { // // Ignore cond. // } else { -// Value* cr = e.cr_value(i.XL.BI >> 2); +// jit_value_t cr = e.cr_value(i.XL.BI >> 2); // cr = b.CreateAnd(cr, 1 << (i.XL.BI & 3)); // if (XESELECTBITS(i.XL.BO, 3, 3)) { // cond_ok = b.CreateICmpNE(cr, b.getInt64(0)); @@ -348,7 +348,7 @@ namespace libjit { // } // // We do a bit of optimization here to make the llvm assembly easier to read. -// Value* ok = NULL; +// jit_value_t ok = NULL; // if (ctr_ok && cond_ok) { // ok = b.CreateAnd(ctr_ok, cond_ok); // } else if (ctr_ok) { @@ -441,7 +441,7 @@ namespace libjit { // // Trap (A-25) // int XeEmitTrap(LibjitEmitter& e, jit_function_t f, InstrData& i, -// Value* va, Value* vb, uint32_t TO) { +// jit_value_t va, jit_value_t vb, uint32_t TO) { // // if (a < b) & TO[0] then TRAP // // if (a > b) & TO[1] then TRAP // // if (a = b) & TO[2] then TRAP @@ -488,35 +488,35 @@ namespace libjit { // // a < b // BasicBlock* bb = *(it++); // b.SetInsertPoint(bb); -// Value* cmp = b.CreateICmpSLT(va, vb); +// jit_value_t cmp = b.CreateICmpSLT(va, vb); // b.CreateCondBr(cmp, trap_bb, *it); // } // if (TO & (1 << 3)) { // // a > b // BasicBlock* bb = *(it++); // b.SetInsertPoint(bb); -// Value* cmp = b.CreateICmpSGT(va, vb); +// jit_value_t cmp = b.CreateICmpSGT(va, vb); // b.CreateCondBr(cmp, trap_bb, *it); // } // if (TO & (1 << 2)) { // // a = b // BasicBlock* bb = *(it++); // b.SetInsertPoint(bb); -// Value* cmp = b.CreateICmpEQ(va, vb); +// jit_value_t cmp = b.CreateICmpEQ(va, vb); // b.CreateCondBr(cmp, trap_bb, *it); // } // if (TO & (1 << 1)) { // // a u b // BasicBlock* bb = *(it++); // b.SetInsertPoint(bb); -// Value* cmp = b.CreateICmpUGT(va, vb); +// jit_value_t cmp = b.CreateICmpUGT(va, vb); // b.CreateCondBr(cmp, trap_bb, *it); // } @@ -573,10 +573,10 @@ namespace libjit { // return XeEmitTrap(e, b, i, // b.CreateSExt(b.CreateTrunc(e.gpr_value(i.X.RA), // b.getInt32Ty()), -// b.getInt64Ty()), +// jit_type_nint), // b.CreateSExt(b.CreateTrunc(e.gpr_value(i.X.RB), // b.getInt32Ty()), -// b.getInt64Ty()), +// jit_type_nint), // i.X.RT); // } @@ -590,7 +590,7 @@ namespace libjit { // return XeEmitTrap(e, b, i, // b.CreateSExt(b.CreateTrunc(e.gpr_value(i.D.RA), // b.getInt32Ty()), -// b.getInt64Ty()), +// jit_type_nint), // b.getInt64(XEEXTS16(i.D.DS)), // i.D.RT); // } @@ -611,7 +611,7 @@ namespace libjit { // // RT <- i32.0 || SPR(n) // const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F); -// Value* v = NULL; +// jit_value_t v = NULL; // switch (n) { // case 1: // // XER @@ -652,7 +652,7 @@ namespace libjit { // // else // // SPR(n) <- (RS)[32:63] -// Value* v = e.gpr_value(i.XFX.RT); +// jit_value_t v = e.gpr_value(i.XFX.RT); // const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F); // switch (n) { diff --git a/src/xenia/cpu/libjit/libjit_emit_memory.cc b/src/xenia/cpu/libjit/libjit_emit_memory.cc index b9f61a093..d624694da 100644 --- a/src/xenia/cpu/libjit/libjit_emit_memory.cc +++ b/src/xenia/cpu/libjit/libjit_emit_memory.cc @@ -29,11 +29,11 @@ namespace libjit { // // EA <- b + EXTS(D) // // RT <- i56.0 || MEM(EA, 1) -// Value* ea = b.getInt64(XEEXTS16(i.D.DS)); +// jit_value_t ea = b.getInt64(XEEXTS16(i.D.DS)); // if (i.D.RA) { // ea = b.CreateAdd(e.gpr_value(i.D.RA), ea); // } -// Value* v = e.ReadMemory(i.address, ea, 1, false); +// jit_value_t v = e.ReadMemory(i.address, ea, 1, false); // e.update_gpr_value(i.D.RT, v); // return 0; @@ -44,8 +44,8 @@ namespace libjit { // // RT <- i56.0 || MEM(EA, 1) // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.D.RA), b.getInt64(XEEXTS16(i.D.DS))); -// Value* v = e.ReadMemory(i.address, ea, 1, false); +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.D.RA), b.getInt64(XEEXTS16(i.D.DS))); +// jit_value_t v = e.ReadMemory(i.address, ea, 1, false); // e.update_gpr_value(i.D.RT, v); // e.update_gpr_value(i.D.RA, ea); @@ -57,8 +57,8 @@ namespace libjit { // // RT <- i56.0 || MEM(EA, 1) // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// Value* v = e.ReadMemory(i.address, ea, 1, false); +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); +// jit_value_t v = e.ReadMemory(i.address, ea, 1, false); // e.update_gpr_value(i.X.RT, v); // e.update_gpr_value(i.X.RA, ea); @@ -73,11 +73,11 @@ namespace libjit { // // EA <- b + (RB) // // RT <- i56.0 || MEM(EA, 1) -// Value* ea = e.gpr_value(i.X.RB); +// jit_value_t ea = e.gpr_value(i.X.RB); // if (i.X.RA) { // ea = b.CreateAdd(e.gpr_value(i.X.RA), ea); // } -// Value* v = e.ReadMemory(i.address, ea, 1, false); +// jit_value_t v = e.ReadMemory(i.address, ea, 1, false); // e.update_gpr_value(i.X.RT, v); // return 0; @@ -91,11 +91,11 @@ namespace libjit { // // EA <- b + EXTS(DS || 0b00) // // RT <- MEM(EA, 8) -// Value* ea = b.getInt64(XEEXTS16(i.DS.DS << 2)); +// jit_value_t ea = b.getInt64(XEEXTS16(i.DS.DS << 2)); // if (i.DS.RA) { // ea = b.CreateAdd(e.gpr_value(i.DS.RA), ea); // } -// Value* v = e.ReadMemory(i.address, ea, 8, false); +// jit_value_t v = e.ReadMemory(i.address, ea, 8, false); // e.update_gpr_value(i.DS.RT, v); // return 0; @@ -106,9 +106,9 @@ namespace libjit { // // RT <- MEM(EA, 8) // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.DS.RA), +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.DS.RA), // b.getInt64(XEEXTS16(i.DS.DS << 2))); -// Value* v = e.ReadMemory(i.address, ea, 8, false); +// jit_value_t v = e.ReadMemory(i.address, ea, 8, false); // e.update_gpr_value(i.DS.RT, v); // e.update_gpr_value(i.DS.RA, ea); @@ -133,12 +133,12 @@ namespace libjit { // // EA <- b + EXTS(D) // // RT <- EXTS(MEM(EA, 2)) -// Value* ea = b.getInt64(XEEXTS16(i.D.DS)); +// jit_value_t ea = b.getInt64(XEEXTS16(i.D.DS)); // if (i.D.RA) { // ea = b.CreateAdd(e.gpr_value(i.D.RA), ea); // } -// Value* v = b.CreateSExt(e.ReadMemory(i.address, ea, 2, false), -// b.getInt64Ty()); +// jit_value_t v = b.CreateSExt(e.ReadMemory(i.address, ea, 2, false), +// jit_type_nint); // e.update_gpr_value(i.D.RT, v); // return 0; @@ -162,12 +162,12 @@ namespace libjit { // // EA <- b + (RB) // // RT <- EXTS(MEM(EA, 2)) -// Value* ea = e.gpr_value(i.X.RB); +// jit_value_t ea = e.gpr_value(i.X.RB); // if (i.X.RA) { // ea = b.CreateAdd(e.gpr_value(i.X.RA), ea); // } -// Value* v = b.CreateSExt(e.ReadMemory(i.address, ea, 2, false), -// b.getInt64Ty()); +// jit_value_t v = b.CreateSExt(e.ReadMemory(i.address, ea, 2, false), +// jit_type_nint); // e.update_gpr_value(i.X.RT, v); // return 0; @@ -181,11 +181,11 @@ namespace libjit { // // EA <- b + EXTS(D) // // RT <- i48.0 || MEM(EA, 2) -// Value* ea = b.getInt64(XEEXTS16(i.D.DS)); +// jit_value_t ea = b.getInt64(XEEXTS16(i.D.DS)); // if (i.D.RA) { // ea = b.CreateAdd(e.gpr_value(i.D.RA), ea); // } -// Value* v = e.ReadMemory(i.address, ea, 2, false); +// jit_value_t v = e.ReadMemory(i.address, ea, 2, false); // e.update_gpr_value(i.D.RT, v); // return 0; @@ -196,8 +196,8 @@ namespace libjit { // // RT <- i48.0 || MEM(EA, 2) // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.D.RA), b.getInt64(XEEXTS16(i.D.DS))); -// Value* v = e.ReadMemory(i.address, ea, 2, false); +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.D.RA), b.getInt64(XEEXTS16(i.D.DS))); +// jit_value_t v = e.ReadMemory(i.address, ea, 2, false); // e.update_gpr_value(i.D.RT, v); // e.update_gpr_value(i.D.RA, ea); @@ -209,8 +209,8 @@ namespace libjit { // // RT <- i48.0 || MEM(EA, 2) // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// Value* v = e.ReadMemory(i.address, ea, 2, false); +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); +// jit_value_t v = e.ReadMemory(i.address, ea, 2, false); // e.update_gpr_value(i.X.RT, v); // e.update_gpr_value(i.X.RA, ea); @@ -225,11 +225,11 @@ namespace libjit { // // EA <- b + (RB) // // RT <- i48.0 || MEM(EA, 2) -// Value* ea = e.gpr_value(i.X.RB); +// jit_value_t ea = e.gpr_value(i.X.RB); // if (i.X.RA) { // ea = b.CreateAdd(e.gpr_value(i.X.RA), ea); // } -// Value* v = e.ReadMemory(i.address, ea, 2, false); +// jit_value_t v = e.ReadMemory(i.address, ea, 2, false); // e.update_gpr_value(i.X.RT, v); // return 0; @@ -243,12 +243,12 @@ namespace libjit { // // EA <- b + EXTS(D || 00) // // RT <- EXTS(MEM(EA, 4)) -// Value* ea = b.getInt64(XEEXTS16(i.DS.DS << 2)); +// jit_value_t ea = b.getInt64(XEEXTS16(i.DS.DS << 2)); // if (i.DS.RA) { // ea = b.CreateAdd(e.gpr_value(i.DS.RA), ea); // } -// Value* v = b.CreateSExt(e.ReadMemory(i.address, ea, 4, false), -// b.getInt64Ty()); +// jit_value_t v = b.CreateSExt(e.ReadMemory(i.address, ea, 4, false), +// jit_type_nint); // e.update_gpr_value(i.DS.RT, v); // return 0; @@ -259,9 +259,9 @@ namespace libjit { // // RT <- EXTS(MEM(EA, 4)) // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// Value* v = b.CreateSExt(e.ReadMemory(i.address, ea, 4, false), -// b.getInt64Ty()); +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); +// jit_value_t v = b.CreateSExt(e.ReadMemory(i.address, ea, 4, false), +// jit_type_nint); // e.update_gpr_value(i.X.RT, v); // e.update_gpr_value(i.X.RA, ea); @@ -276,12 +276,12 @@ namespace libjit { // // EA <- b + (RB) // // RT <- EXTS(MEM(EA, 4)) -// Value* ea = e.gpr_value(i.X.RB); +// jit_value_t ea = e.gpr_value(i.X.RB); // if (i.X.RA) { // ea = b.CreateAdd(e.gpr_value(i.X.RA), ea); // } -// Value* v = b.CreateSExt(e.ReadMemory(i.address, ea, 4, false), -// b.getInt64Ty()); +// jit_value_t v = b.CreateSExt(e.ReadMemory(i.address, ea, 4, false), +// jit_type_nint); // e.update_gpr_value(i.X.RT, v); // return 0; @@ -295,11 +295,11 @@ namespace libjit { // // EA <- b + EXTS(D) // // RT <- i32.0 || MEM(EA, 4) -// Value* ea = b.getInt64(XEEXTS16(i.D.DS)); +// jit_value_t ea = b.getInt64(XEEXTS16(i.D.DS)); // if (i.D.RA) { // ea = b.CreateAdd(e.gpr_value(i.D.RA), ea); // } -// Value* v = e.ReadMemory(i.address, ea, 4, false); +// jit_value_t v = e.ReadMemory(i.address, ea, 4, false); // e.update_gpr_value(i.D.RT, v); // return 0; @@ -310,8 +310,8 @@ namespace libjit { // // RT <- i32.0 || MEM(EA, 4) // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.D.RA), b.getInt64(XEEXTS16(i.D.DS))); -// Value* v = e.ReadMemory(i.address, ea, 4, false); +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.D.RA), b.getInt64(XEEXTS16(i.D.DS))); +// jit_value_t v = e.ReadMemory(i.address, ea, 4, false); // e.update_gpr_value(i.D.RT, v); // e.update_gpr_value(i.D.RA, ea); @@ -323,8 +323,8 @@ namespace libjit { // // RT <- i32.0 || MEM(EA, 4) // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// Value* v = e.ReadMemory(i.address, ea, 4, false); +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); +// jit_value_t v = e.ReadMemory(i.address, ea, 4, false); // e.update_gpr_value(i.X.RT, v); // e.update_gpr_value(i.X.RA, ea); @@ -339,11 +339,11 @@ namespace libjit { // // EA <- b + (RB) // // RT <- i32.0 || MEM(EA, 4) -// Value* ea = e.gpr_value(i.X.RB); +// jit_value_t ea = e.gpr_value(i.X.RB); // if (i.X.RA) { // ea = b.CreateAdd(e.gpr_value(i.X.RA), ea); // } -// Value* v = e.ReadMemory(i.address, ea, 4, false); +// jit_value_t v = e.ReadMemory(i.address, ea, 4, false); // e.update_gpr_value(i.X.RT, v); // return 0; @@ -360,11 +360,11 @@ namespace libjit { // // EA <- b + EXTS(D) // // MEM(EA, 1) <- (RS)[56:63] -// Value* ea = b.getInt64(XEEXTS16(i.D.DS)); +// jit_value_t ea = b.getInt64(XEEXTS16(i.D.DS)); // if (i.D.RA) { // ea = b.CreateAdd(e.gpr_value(i.D.RA), ea); // } -// Value* v = e.gpr_value(i.D.RT); +// jit_value_t v = e.gpr_value(i.D.RT); // e.WriteMemory(i.address, ea, 1, v); // return 0; @@ -375,8 +375,8 @@ namespace libjit { // // MEM(EA, 1) <- (RS)[56:63] // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.D.RA), b.getInt64(XEEXTS16(i.D.DS))); -// Value* v = e.gpr_value(i.D.RT); +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.D.RA), b.getInt64(XEEXTS16(i.D.DS))); +// jit_value_t v = e.gpr_value(i.D.RT); // e.WriteMemory(i.address, ea, 1, v); // e.update_gpr_value(i.D.RA, ea); @@ -388,8 +388,8 @@ namespace libjit { // // MEM(EA, 1) <- (RS)[56:63] // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// Value* v = e.gpr_value(i.X.RT); +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); +// jit_value_t v = e.gpr_value(i.X.RT); // e.WriteMemory(i.address, ea, 1, v); // e.update_gpr_value(i.X.RA, ea); @@ -404,11 +404,11 @@ namespace libjit { // // EA <- b + (RB) // // MEM(EA, 1) <- (RS)[56:63] -// Value* ea = e.gpr_value(i.X.RB); +// jit_value_t ea = e.gpr_value(i.X.RB); // if (i.D.RA) { // ea = b.CreateAdd(e.gpr_value(i.X.RA), ea); // } -// Value* v = e.gpr_value(i.X.RT); +// jit_value_t v = e.gpr_value(i.X.RT); // e.WriteMemory(i.address, ea, 1, v); // return 0; @@ -422,11 +422,11 @@ namespace libjit { // // EA <- b + EXTS(DS || 0b00) // // MEM(EA, 8) <- (RS) -// Value* ea = b.getInt64(XEEXTS16(i.DS.DS << 2)); +// jit_value_t ea = b.getInt64(XEEXTS16(i.DS.DS << 2)); // if (i.DS.RA) { // ea = b.CreateAdd(e.gpr_value(i.DS.RA), ea); // } -// Value* v = e.gpr_value(i.DS.RT); +// jit_value_t v = e.gpr_value(i.DS.RT); // e.WriteMemory(i.address, ea, 8, v); // return 0; @@ -437,9 +437,9 @@ namespace libjit { // // MEM(EA, 8) <- (RS) // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.DS.RA), +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.DS.RA), // b.getInt64(XEEXTS16(i.DS.DS << 2))); -// Value* v = e.gpr_value(i.DS.RT); +// jit_value_t v = e.gpr_value(i.DS.RT); // e.WriteMemory(i.address, ea, 8, v); // e.update_gpr_value(i.DS.RA, ea); @@ -454,11 +454,11 @@ namespace libjit { // // EA <- b + (RB) // // MEM(EA, 8) <- (RS) -// Value* ea = e.gpr_value(i.X.RB); +// jit_value_t ea = e.gpr_value(i.X.RB); // if (i.X.RA) { // ea = b.CreateAdd(e.gpr_value(i.X.RA), ea); // } -// Value* v = e.gpr_value(i.X.RT); +// jit_value_t v = e.gpr_value(i.X.RT); // e.WriteMemory(i.address, ea, 8, v); // return 0; @@ -469,8 +469,8 @@ namespace libjit { // // MEM(EA, 8) <- (RS) // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// Value* v = e.gpr_value(i.X.RT); +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); +// jit_value_t v = e.gpr_value(i.X.RT); // e.WriteMemory(i.address, ea, 8, v); // e.update_gpr_value(i.X.RA, ea); @@ -485,11 +485,11 @@ namespace libjit { // // EA <- b + EXTS(D) // // MEM(EA, 2) <- (RS)[48:63] -// Value* ea = b.getInt64(XEEXTS16(i.D.DS)); +// jit_value_t ea = b.getInt64(XEEXTS16(i.D.DS)); // if (i.D.RA) { // ea = b.CreateAdd(e.gpr_value(i.D.RA), ea); // } -// Value* v = e.gpr_value(i.D.RT); +// jit_value_t v = e.gpr_value(i.D.RT); // e.WriteMemory(i.address, ea, 2, v); // return 0; @@ -500,9 +500,9 @@ namespace libjit { // // MEM(EA, 2) <- (RS)[48:63] // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.D.RA), +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.D.RA), // b.getInt64(XEEXTS16(i.D.DS))); -// Value* v = e.gpr_value(i.D.RT); +// jit_value_t v = e.gpr_value(i.D.RT); // e.WriteMemory(i.address, ea, 2, v); // e.update_gpr_value(i.D.RA, ea); @@ -514,8 +514,8 @@ namespace libjit { // // MEM(EA, 2) <- (RS)[48:63] // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// Value* v = e.gpr_value(i.X.RT); +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); +// jit_value_t v = e.gpr_value(i.X.RT); // e.WriteMemory(i.address, ea, 2, v); // e.update_gpr_value(i.X.RA, ea); @@ -530,11 +530,11 @@ namespace libjit { // // EA <- b + (RB) // // MEM(EA, 2) <- (RS)[48:63] -// Value* ea = e.gpr_value(i.X.RB); +// jit_value_t ea = e.gpr_value(i.X.RB); // if (i.D.RA) { // ea = b.CreateAdd(e.gpr_value(i.X.RA), ea); // } -// Value* v = e.gpr_value(i.X.RT); +// jit_value_t v = e.gpr_value(i.X.RT); // e.WriteMemory(i.address, ea, 2, v); // return 0; @@ -548,11 +548,11 @@ namespace libjit { // // EA <- b + EXTS(D) // // MEM(EA, 4) <- (RS)[32:63] -// Value* ea = b.getInt64(XEEXTS16(i.D.DS)); +// jit_value_t ea = b.getInt64(XEEXTS16(i.D.DS)); // if (i.D.RA) { // ea = b.CreateAdd(e.gpr_value(i.D.RA), ea); // } -// Value* v = e.gpr_value(i.D.RT); +// jit_value_t v = e.gpr_value(i.D.RT); // e.WriteMemory(i.address, ea, 4, v); // return 0; @@ -563,9 +563,9 @@ namespace libjit { // // MEM(EA, 4) <- (RS)[32:63] // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.D.RA), +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.D.RA), // b.getInt64(XEEXTS16(i.D.DS))); -// Value* v = e.gpr_value(i.D.RT); +// jit_value_t v = e.gpr_value(i.D.RT); // e.WriteMemory(i.address, ea, 4, v); // e.update_gpr_value(i.D.RA, ea); @@ -577,8 +577,8 @@ namespace libjit { // // MEM(EA, 4) <- (RS)[32:63] // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// Value* v = e.gpr_value(i.X.RT); +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); +// jit_value_t v = e.gpr_value(i.X.RT); // e.WriteMemory(i.address, ea, 4, v); // e.update_gpr_value(i.X.RA, ea); @@ -593,11 +593,11 @@ namespace libjit { // // EA <- b + (RB) // // MEM(EA, 4) <- (RS)[32:63] -// Value* ea = e.gpr_value(i.X.RB); +// jit_value_t ea = e.gpr_value(i.X.RB); // if (i.X.RA) { // ea = b.CreateAdd(e.gpr_value(i.X.RA), ea); // } -// Value* v = e.gpr_value(i.X.RT); +// jit_value_t v = e.gpr_value(i.X.RT); // e.WriteMemory(i.address, ea, 4, v); // return 0; @@ -703,11 +703,11 @@ namespace libjit { // // TODO(benvanik): make this right -// Value* ea = e.gpr_value(i.X.RB); +// jit_value_t ea = e.gpr_value(i.X.RB); // if (i.X.RA) { // ea = b.CreateAdd(e.gpr_value(i.X.RA), ea); // } -// Value* v = e.ReadMemory(i.address, ea, 4, /* acquire */ true); +// jit_value_t v = e.ReadMemory(i.address, ea, 4, /* acquire */ true); // e.update_gpr_value(i.X.RT, v); // return 0; @@ -731,11 +731,11 @@ namespace libjit { // // TODO(benvanik): make this right -// Value* ea = b.getInt64(XEEXTS16(i.D.DS)); +// jit_value_t ea = b.getInt64(XEEXTS16(i.D.DS)); // if (i.D.RA) { // ea = b.CreateAdd(e.gpr_value(i.D.RA), ea); // } -// Value* v = e.gpr_value(i.D.RT); +// jit_value_t v = e.gpr_value(i.D.RT); // e.WriteMemory(i.address, ea, 4, v, /* release */ true); // // We always succeed. @@ -760,12 +760,12 @@ namespace libjit { // // EA <- b + EXTS(D) // // FRT <- MEM(EA, 8) -// Value* ea = b.getInt64(XEEXTS16(i.D.DS)); +// jit_value_t ea = b.getInt64(XEEXTS16(i.D.DS)); // if (i.D.RA) { // ea = b.CreateAdd(e.gpr_value(i.D.RA), ea); // } -// Value* v = e.ReadMemory(i.address, ea, 8, false); -// v = b.CreateBitCast(v, b.getDoubleTy()); +// jit_value_t v = e.ReadMemory(i.address, ea, 8, false); +// v = b.CreateBitCast(v, jit_type_float64); // e.update_fpr_value(i.D.RT, v); // return 0; @@ -776,9 +776,9 @@ namespace libjit { // // FRT <- MEM(EA, 8) // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.D.RA), b.getInt64(XEEXTS16(i.D.DS))); -// Value* v = e.ReadMemory(i.address, ea, 8, false); -// v = b.CreateBitCast(v, b.getDoubleTy()); +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.D.RA), b.getInt64(XEEXTS16(i.D.DS))); +// jit_value_t v = e.ReadMemory(i.address, ea, 8, false); +// v = b.CreateBitCast(v, jit_type_float64); // e.update_fpr_value(i.D.RT, v); // e.update_gpr_value(i.D.RA, ea); @@ -790,9 +790,9 @@ namespace libjit { // // FRT <- MEM(EA, 8) // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// Value* v = e.ReadMemory(i.address, ea, 8, false); -// v = b.CreateBitCast(v, b.getDoubleTy()); +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); +// jit_value_t v = e.ReadMemory(i.address, ea, 8, false); +// v = b.CreateBitCast(v, jit_type_float64); // e.update_fpr_value(i.X.RT, v); // e.update_gpr_value(i.X.RA, ea); @@ -807,12 +807,12 @@ namespace libjit { // // EA <- b + (RB) // // FRT <- MEM(EA, 8) -// Value* ea = e.gpr_value(i.X.RB); +// jit_value_t ea = e.gpr_value(i.X.RB); // if (i.X.RA) { // ea = b.CreateAdd(e.gpr_value(i.X.RA), ea); // } -// Value* v = e.ReadMemory(i.address, ea, 8, false); -// v = b.CreateBitCast(v, b.getDoubleTy()); +// jit_value_t v = e.ReadMemory(i.address, ea, 8, false); +// v = b.CreateBitCast(v, jit_type_float64); // e.update_fpr_value(i.X.RT, v); // return 0; @@ -826,12 +826,12 @@ namespace libjit { // // EA <- b + EXTS(D) // // FRT <- DOUBLE(MEM(EA, 4)) -// Value* ea = b.getInt64(XEEXTS16(i.D.DS)); +// jit_value_t ea = b.getInt64(XEEXTS16(i.D.DS)); // if (i.D.RA) { // ea = b.CreateAdd(e.gpr_value(i.D.RA), ea); // } -// Value* v = e.ReadMemory(i.address, ea, 4, false); -// v = b.CreateFPExt(b.CreateBitCast(v, b.getFloatTy()), b.getDoubleTy()); +// jit_value_t v = e.ReadMemory(i.address, ea, 4, false); +// v = b.CreateFPExt(b.CreateBitCast(v, b.getFloatTy()), jit_type_float64); // e.update_fpr_value(i.D.RT, v); // return 0; @@ -842,9 +842,9 @@ namespace libjit { // // FRT <- DOUBLE(MEM(EA, 4)) // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.D.RA), b.getInt64(XEEXTS16(i.D.DS))); -// Value* v = e.ReadMemory(i.address, ea, 4, false); -// v = b.CreateFPExt(b.CreateBitCast(v, b.getFloatTy()), b.getDoubleTy()); +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.D.RA), b.getInt64(XEEXTS16(i.D.DS))); +// jit_value_t v = e.ReadMemory(i.address, ea, 4, false); +// v = b.CreateFPExt(b.CreateBitCast(v, b.getFloatTy()), jit_type_float64); // e.update_fpr_value(i.D.RT, v); // e.update_gpr_value(i.D.RA, ea); @@ -856,9 +856,9 @@ namespace libjit { // // FRT <- DOUBLE(MEM(EA, 4)) // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// Value* v = e.ReadMemory(i.address, ea, 4, false); -// v = b.CreateFPExt(b.CreateBitCast(v, b.getFloatTy()), b.getDoubleTy()); +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); +// jit_value_t v = e.ReadMemory(i.address, ea, 4, false); +// v = b.CreateFPExt(b.CreateBitCast(v, b.getFloatTy()), jit_type_float64); // e.update_fpr_value(i.X.RT, v); // e.update_gpr_value(i.X.RA, ea); @@ -873,12 +873,12 @@ namespace libjit { // // EA <- b + (RB) // // FRT <- DOUBLE(MEM(EA, 4)) -// Value* ea = e.gpr_value(i.X.RB); +// jit_value_t ea = e.gpr_value(i.X.RB); // if (i.X.RA) { // ea = b.CreateAdd(e.gpr_value(i.X.RA), ea); // } -// Value* v = e.ReadMemory(i.address, ea, 4, false); -// v = b.CreateFPExt(b.CreateBitCast(v, b.getFloatTy()), b.getDoubleTy()); +// jit_value_t v = e.ReadMemory(i.address, ea, 4, false); +// v = b.CreateFPExt(b.CreateBitCast(v, b.getFloatTy()), jit_type_float64); // e.update_fpr_value(i.X.RT, v); // return 0; @@ -895,12 +895,12 @@ namespace libjit { // // EA <- b + EXTS(D) // // MEM(EA, 8) <- (FRS) -// Value* ea = b.getInt64(XEEXTS16(i.D.DS)); +// jit_value_t ea = b.getInt64(XEEXTS16(i.D.DS)); // if (i.D.RA) { // ea = b.CreateAdd(e.gpr_value(i.D.RA), ea); // } -// Value* v = e.fpr_value(i.D.RT); -// v = b.CreateBitCast(v, b.getInt64Ty()); +// jit_value_t v = e.fpr_value(i.D.RT); +// v = b.CreateBitCast(v, jit_type_nint); // e.WriteMemory(i.address, ea, 8, v); // return 0; @@ -911,10 +911,10 @@ namespace libjit { // // MEM(EA, 8) <- (FRS) // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.D.RA), +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.D.RA), // b.getInt64(XEEXTS16(i.D.DS))); -// Value* v = e.fpr_value(i.D.RT); -// v = b.CreateBitCast(v, b.getInt64Ty()); +// jit_value_t v = e.fpr_value(i.D.RT); +// v = b.CreateBitCast(v, jit_type_nint); // e.WriteMemory(i.address, ea, 8, v); // e.update_gpr_value(i.D.RA, ea); @@ -926,9 +926,9 @@ namespace libjit { // // MEM(EA, 8) <- (FRS) // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// Value* v = e.fpr_value(i.X.RT); -// v = b.CreateBitCast(v, b.getInt64Ty()); +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); +// jit_value_t v = e.fpr_value(i.X.RT); +// v = b.CreateBitCast(v, jit_type_nint); // e.WriteMemory(i.address, ea, 8, v); // e.update_gpr_value(i.X.RA, ea); @@ -943,12 +943,12 @@ namespace libjit { // // EA <- b + (RB) // // MEM(EA, 8) <- (FRS) -// Value* ea = e.gpr_value(i.X.RB); +// jit_value_t ea = e.gpr_value(i.X.RB); // if (i.X.RA) { // ea = b.CreateAdd(e.gpr_value(i.X.RA), ea); // } -// Value* v = e.fpr_value(i.X.RT); -// v = b.CreateBitCast(v, b.getInt64Ty()); +// jit_value_t v = e.fpr_value(i.X.RT); +// v = b.CreateBitCast(v, jit_type_nint); // e.WriteMemory(i.address, ea, 8, v); // return 0; @@ -962,12 +962,12 @@ namespace libjit { // // EA <- b + (RB) // // MEM(EA, 4) <- (FRS)[32:63] -// Value* ea = e.gpr_value(i.X.RB); +// jit_value_t ea = e.gpr_value(i.X.RB); // if (i.X.RA) { // ea = b.CreateAdd(e.gpr_value(i.D.RA), ea); // } -// Value* v = e.fpr_value(i.X.RT); -// v = b.CreateBitCast(v, b.getInt64Ty()); +// jit_value_t v = e.fpr_value(i.X.RT); +// v = b.CreateBitCast(v, jit_type_nint); // e.WriteMemory(i.address, ea, 4, v); // return 0; @@ -981,11 +981,11 @@ namespace libjit { // // EA <- b + EXTS(D) // // MEM(EA, 4) <- SINGLE(FRS) -// Value* ea = b.getInt64(XEEXTS16(i.D.DS)); +// jit_value_t ea = b.getInt64(XEEXTS16(i.D.DS)); // if (i.D.RA) { // ea = b.CreateAdd(e.gpr_value(i.D.RA), ea); // } -// Value* v = e.fpr_value(i.D.RT); +// jit_value_t v = e.fpr_value(i.D.RT); // v = b.CreateBitCast(b.CreateFPTrunc(v, b.getFloatTy()), b.getInt32Ty()); // e.WriteMemory(i.address, ea, 4, v); @@ -997,9 +997,9 @@ namespace libjit { // // MEM(EA, 4) <- SINGLE(FRS) // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.D.RA), +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.D.RA), // b.getInt64(XEEXTS16(i.D.DS))); -// Value* v = e.fpr_value(i.D.RT); +// jit_value_t v = e.fpr_value(i.D.RT); // v = b.CreateBitCast(b.CreateFPTrunc(v, b.getFloatTy()), b.getInt32Ty()); // e.WriteMemory(i.address, ea, 4, v); // e.update_gpr_value(i.D.RA, ea); @@ -1012,8 +1012,8 @@ namespace libjit { // // MEM(EA, 4) <- SINGLE(FRS) // // RA <- EA -// Value* ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// Value* v = e.fpr_value(i.X.RT); +// jit_value_t ea = b.CreateAdd(e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); +// jit_value_t v = e.fpr_value(i.X.RT); // v = b.CreateBitCast(b.CreateFPTrunc(v, b.getFloatTy()), b.getInt32Ty()); // e.WriteMemory(i.address, ea, 4, v); // e.update_gpr_value(i.X.RA, ea); @@ -1029,11 +1029,11 @@ namespace libjit { // // EA <- b + (RB) // // MEM(EA, 4) <- SINGLE(FRS) -// Value* ea = e.gpr_value(i.X.RB); +// jit_value_t ea = e.gpr_value(i.X.RB); // if (i.X.RA) { // ea = b.CreateAdd(e.gpr_value(i.X.RA), ea); // } -// Value* v = e.fpr_value(i.X.RT); +// jit_value_t v = e.fpr_value(i.X.RT); // v = b.CreateBitCast(b.CreateFPTrunc(v, b.getFloatTy()), b.getInt32Ty()); // e.WriteMemory(i.address, ea, 4, v); diff --git a/src/xenia/cpu/libjit/libjit_emitter.cc b/src/xenia/cpu/libjit/libjit_emitter.cc index ca85120b2..2e055ca2e 100644 --- a/src/xenia/cpu/libjit/libjit_emitter.cc +++ b/src/xenia/cpu/libjit/libjit_emitter.cc @@ -162,14 +162,12 @@ int LibjitEmitter::MakeFunction(FunctionSymbol* symbol, jit_function_t fn) { symbol_ = symbol; fn_ = fn; - // symbol_block_ = NULL; - // return_block_ = NULL; - // internal_indirection_block_ = NULL; - // external_indirection_block_ = NULL; - // bb_ = NULL; + fn_block_ = NULL; + return_block_ = jit_label_undefined; + internal_indirection_block_ = jit_label_undefined; + external_indirection_block_ = jit_label_undefined; - // insert_points_.clear(); - // bbs_.clear(); + bbs_.clear(); cia_ = 0; @@ -245,8 +243,7 @@ int LibjitEmitter::MakeUserFunction() { } // Emit. - //emitter_->GenerateBasicBlocks(); - jit_insn_return(fn_, NULL); + GenerateBasicBlocks(); return 0; } @@ -320,91 +317,58 @@ jit_function_t LibjitEmitter::fn() { return fn_; } -//FunctionBlock* LibjitEmitter::symbol_block() { -// return symbol_block_; -//} -// -//void LibjitEmitter::PushInsertPoint() { -// IRBuilder<>& b = *builder_; -// insert_points_.push_back(std::pair( -// b.GetInsertBlock(), b.GetInsertPoint())); -//} -// -//void LibjitEmitter::PopInsertPoint() { -// IRBuilder<>& b = *builder_; -// std::pair back = insert_points_.back(); -// b.SetInsertPoint(back.first, back.second); -// insert_points_.pop_back(); -//} -// -//void LibjitEmitter::GenerateBasicBlocks() { -// IRBuilder<>& b = *builder_; -// -// // Always add an entry block. -// BasicBlock* entry = BasicBlock::Create(*context_, "entry", fn_); -// b.SetInsertPoint(entry); -// -// if (FLAGS_trace_user_calls) { -// SpillRegisters(); -// Value* traceUserCall = gen_module_->getFunction("XeTraceUserCall"); -// b.CreateCall4( -// traceUserCall, -// fn_->arg_begin(), -// b.getInt64(symbol_->start_address), -// ++fn_->arg_begin(), -// b.getInt64((uint64_t)symbol_)); -// } -// -// // If this function is empty, abort! -// if (!symbol_->blocks.size()) { -// b.CreateRetVoid(); -// return; -// } -// -// // Create a return block. -// // This spills registers and returns. All non-tail returns should branch -// // here to do the return and ensure registers are spilled. -// return_block_ = BasicBlock::Create(*context_, "return", fn_); -// -// // Pass 1 creates all of the blocks - this way we can branch to them. -// // We also track registers used so that when know which ones to fill/spill. -// for (std::map::iterator it = symbol_->blocks.begin(); -// it != symbol_->blocks.end(); ++it) { -// FunctionBlock* block = it->second; -// XEIGNORE(PrepareBasicBlock(block)); -// } -// -// // Setup all local variables now that we know what we need. -// SetupLocals(); -// -// // Pass 2 fills in instructions. -// for (std::map::iterator it = symbol_->blocks.begin(); -// it != symbol_->blocks.end(); ++it) { -// FunctionBlock* block = it->second; -// GenerateBasicBlock(block); -// } -// -// // Setup the shared return/indirection/etc blocks now that we know all the -// // blocks we need and all the registers used. -// GenerateSharedBlocks(); -//} -// -//void LibjitEmitter::GenerateSharedBlocks() { -// IRBuilder<>& b = *builder_; -// -// Value* indirect_branch = gen_module_->getFunction("XeIndirectBranch"); -// -// // Setup initial register fill in the entry block. -// // We can only do this once all the locals have been created. -// b.SetInsertPoint(&fn_->getEntryBlock()); -// FillRegisters(); -// // Entry always falls through to the second block. -// b.CreateBr(bbs_.begin()->second); -// -// // Setup the spill block in return. -// b.SetInsertPoint(return_block_); -// SpillRegisters(); -// b.CreateRetVoid(); +FunctionBlock* LibjitEmitter::fn_block() { + return fn_block_; +} + +void LibjitEmitter::GenerateBasicBlocks() { + // If this function is empty, abort! + if (!symbol_->blocks.size()) { + jit_insn_return(fn_, NULL); + return; + } + + // Pass 1 creates all of the labels - this way we can branch to them. + // We also track registers used so that when know which ones to fill/spill. + // No actual blocks or instructions are created here. + // TODO(benvanik): move this to SDB? would remove an entire pass over the + // code. + for (std::map::iterator it = + symbol_->blocks.begin(); it != symbol_->blocks.end(); ++it) { + FunctionBlock* block = it->second; + XEIGNORE(PrepareBasicBlock(block)); + } + + // Setup all local variables now that we know what we need. + // This happens in the entry block. + SetupLocals(); + + // Setup initial register fill in the entry block. + // We can only do this once all the locals have been created. + FillRegisters(); + + // Pass 2 fills in instructions. + for (std::map::iterator it = symbol_->blocks.begin(); + it != symbol_->blocks.end(); ++it) { + FunctionBlock* block = it->second; + GenerateBasicBlock(block); + } + + // Setup the shared return/indirection/etc blocks now that we know all the + // blocks we need and all the registers used. + GenerateSharedBlocks(); +} + +void LibjitEmitter::GenerateSharedBlocks() { + // Create a return block. + // This spills registers and returns. All non-tail returns should branch + // here to do the return and ensure registers are spilled. + // This will be moved to the end after all the other blocks are created. + jit_insn_label(fn_, &return_block_); + SpillRegisters(); + jit_insn_return(fn_, NULL); + +// jit_value_t indirect_branch = gen_module_->getFunction("XeIndirectBranch"); // // // Build indirection block on demand. // // We have already prepped all basic blocks, so we can build these tables now. @@ -434,177 +398,200 @@ jit_function_t LibjitEmitter::fn() { // switch_i->addCase(b.getInt64(it->first), it->second); // } // } -//} -// -//int LibjitEmitter::PrepareBasicBlock(FunctionBlock* block) { -// // Create the basic block that will end up getting filled during -// // generation. -// char name[32]; -// xesnprintfa(name, XECOUNT(name), "loc_%.8X", block->start_address); -// BasicBlock* bb = BasicBlock::Create(*context_, name, fn_); -// bbs_.insert(std::pair(block->start_address, bb)); -// -// // Scan and disassemble each instruction in the block to get accurate -// // register access bits. In the future we could do other optimization checks -// // in this pass. -// // TODO(benvanik): perhaps we want to stash this for each basic block? -// // We could use this for faster checking of cr/ca checks/etc. -// InstrAccessBits access_bits; -// uint8_t* p = xe_memory_addr(memory_, 0); -// for (uint32_t ia = block->start_address; ia <= block->end_address; ia += 4) { -// InstrData i; -// i.address = ia; -// i.code = XEGETUINT32BE(p + ia); -// i.type = ppc::GetInstrType(i.code); -// -// // Ignore unknown or ones with no disassembler fn. -// if (!i.type || !i.type->disassemble) { -// continue; -// } -// -// // We really need to know the registers modified, so die if we've been lazy -// // and haven't implemented the disassemble method yet. -// ppc::InstrDisasm d; -// XEASSERTNOTNULL(i.type->disassemble); -// int result_code = i.type->disassemble(i, d); -// XEASSERTZERO(result_code); -// if (result_code) { -// return result_code; -// } -// -// // Accumulate access bits. -// access_bits.Extend(d.access_bits); -// } -// -// // Add in access bits to function access bits. -// access_bits_.Extend(access_bits); -// -// return 0; -//} -// -//void LibjitEmitter::GenerateBasicBlock(FunctionBlock* block) { -// IRBuilder<>& b = *builder_; -// -// BasicBlock* bb = GetBasicBlock(block->start_address); -// XEASSERTNOTNULL(bb); -// -// if (FLAGS_log_codegen) { -// printf(" bb %.8X-%.8X:\n", block->start_address, block->end_address); -// } -// -// symbol_block_ = block; -// bb_ = bb; -// -// // Move the builder to this block and setup. -// b.SetInsertPoint(bb); -// //i->setMetadata("some.name", MDNode::get(context, MDString::get(context, pname))); -// -// Value* invalidInstruction = -// gen_module_->getFunction("XeInvalidInstruction"); -// Value* traceInstruction = -// gen_module_->getFunction("XeTraceInstruction"); -// -// // Walk instructions in block. -// uint8_t* p = xe_memory_addr(memory_, 0); -// for (uint32_t ia = block->start_address; ia <= block->end_address; ia += 4) { -// InstrData i; -// i.address = ia; -// i.code = XEGETUINT32BE(p + ia); -// i.type = ppc::GetInstrType(i.code); -// -// if (FLAGS_trace_instructions) { -// SpillRegisters(); -// b.CreateCall3( -// traceInstruction, -// fn_->arg_begin(), -// b.getInt32(i.address), -// b.getInt32(i.code)); -// } -// -// if (!i.type) { -// XELOGCPU("Invalid instruction %.8X %.8X", ia, i.code); -// SpillRegisters(); -// b.CreateCall3( -// invalidInstruction, -// fn_->arg_begin(), -// b.getInt32(i.address), -// b.getInt32(i.code)); -// continue; -// } -// -// if (FLAGS_log_codegen) { -// if (i.type->disassemble) { -// ppc::InstrDisasm d; -// i.type->disassemble(i, d); -// std::string disasm; -// d.Dump(disasm); -// printf(" %.8X: %.8X %s\n", ia, i.code, disasm.c_str()); -// } else { -// printf(" %.8X: %.8X %s ???\n", ia, i.code, i.type->name); -// } -// } -// -// // TODO(benvanik): debugging information? source/etc? -// // builder_>SetCurrentDebugLocation(DebugLoc::get( -// // ia >> 8, ia & 0xFF, ctx->cu)); -// -// typedef int (*InstrEmitter)(LibjitEmitter& g, IRBuilder<>& b, -// InstrData& i); -// InstrEmitter emit = (InstrEmitter)i.type->emit; -// if (!i.type->emit || emit(*this, *builder_, i)) { -// // This printf is handy for sort/uniquify to find instructions. -// //printf("unimplinstr %s\n", i.type->name); -// -// XELOGCPU("Unimplemented instr %.8X %.8X %s", -// ia, i.code, i.type->name); -// SpillRegisters(); -// b.CreateCall3( -// invalidInstruction, -// fn_->arg_begin(), -// b.getInt32(i.address), -// b.getInt32(i.code)); -// } -// } -// -// // If we fall through, create the branch. -// if (block->outgoing_type == FunctionBlock::kTargetNone) { -// BasicBlock* next_bb = GetNextBasicBlock(); -// XEASSERTNOTNULL(next_bb); -// b.CreateBr(next_bb); -// } else if (block->outgoing_type == FunctionBlock::kTargetUnknown) { -// // Hrm. -// // TODO(benvanik): assert this doesn't occur - means a bad sdb run! -// XELOGCPU("SDB function scan error in %.8X: bb %.8X has unknown exit", -// symbol_->start_address, block->start_address); -// b.CreateRetVoid(); -// } -// -// // TODO(benvanik): finish up BB -//} -// -//BasicBlock* LibjitEmitter::GetBasicBlock(uint32_t address) { -// std::map::iterator it = bbs_.find(address); -// if (it != bbs_.end()) { -// return it->second; -// } -// return NULL; -//} -// +} + +int LibjitEmitter::PrepareBasicBlock(FunctionBlock* block) { + // Add an undefined entry in the table. + // The label will be created on-demand. + bbs_.insert(std::pair( + block->start_address, jit_label_undefined)); + + // TODO(benvanik): set label name? would help debugging disasm + // char name[32]; + // xesnprintfa(name, XECOUNT(name), "loc_%.8X", block->start_address); + + // Scan and disassemble each instruction in the block to get accurate + // register access bits. In the future we could do other optimization checks + // in this pass. + // TODO(benvanik): perhaps we want to stash this for each basic block? + // We could use this for faster checking of cr/ca checks/etc. + InstrAccessBits access_bits; + uint8_t* p = xe_memory_addr(memory_, 0); + for (uint32_t ia = block->start_address; ia <= block->end_address; ia += 4) { + InstrData i; + i.address = ia; + i.code = XEGETUINT32BE(p + ia); + i.type = ppc::GetInstrType(i.code); + + // Ignore unknown or ones with no disassembler fn. + if (!i.type || !i.type->disassemble) { + continue; + } + + // We really need to know the registers modified, so die if we've been lazy + // and haven't implemented the disassemble method yet. + ppc::InstrDisasm d; + XEASSERTNOTNULL(i.type->disassemble); + int result_code = i.type->disassemble(i, d); + XEASSERTZERO(result_code); + if (result_code) { + return result_code; + } + + // Accumulate access bits. + access_bits.Extend(d.access_bits); + } + + // Add in access bits to function access bits. + access_bits_.Extend(access_bits); + + return 0; +} + +void LibjitEmitter::GenerateBasicBlock(FunctionBlock* block) { + fn_block_ = block; + + // Create new block. + // This will create a label if it hasn't already been done. + std::map::iterator label_it = + bbs_.find(block->start_address); + XEASSERT(label_it != bbs_.end()); + jit_insn_label(fn_, &label_it->second); + + if (FLAGS_log_codegen) { + printf(" bb %.8X-%.8X:\n", block->start_address, block->end_address); + } + + // Walk instructions in block. + uint8_t* p = xe_memory_addr(memory_, 0); + for (uint32_t ia = block->start_address; ia <= block->end_address; ia += 4) { + InstrData i; + i.address = ia; + i.code = XEGETUINT32BE(p + ia); + i.type = ppc::GetInstrType(i.code); + + jit_value_t trace_args[] = { + jit_value_get_param(fn_, 0), + jit_value_create_long_constant(fn_, jit_type_ulong, + (jit_ulong)i.address), + jit_value_create_long_constant(fn_, jit_type_ulong, + (jit_ulong)i.code), + }; + + // Add debugging tag. + // TODO(benvanik): mark type. + jit_insn_mark_breakpoint(fn_, 1, ia); + + if (FLAGS_trace_instructions) { + SpillRegisters(); + jit_insn_call_native( + fn_, + "XeTraceInstruction", + global_exports_.XeTraceInstruction, + global_export_signature_3_, + trace_args, XECOUNT(trace_args), + 0); + } + + if (!i.type) { + XELOGCPU("Invalid instruction %.8X %.8X", ia, i.code); + SpillRegisters(); + jit_insn_call_native( + fn_, + "XeInvalidInstruction", + global_exports_.XeInvalidInstruction, + global_export_signature_3_, + trace_args, XECOUNT(trace_args), + 0); + continue; + } + + if (FLAGS_log_codegen) { + if (i.type->disassemble) { + ppc::InstrDisasm d; + i.type->disassemble(i, d); + std::string disasm; + d.Dump(disasm); + printf(" %.8X: %.8X %s\n", ia, i.code, disasm.c_str()); + } else { + printf(" %.8X: %.8X %s ???\n", ia, i.code, i.type->name); + } + } + + typedef int (*InstrEmitter)(LibjitEmitter& g, jit_function_t f, + InstrData& i); + InstrEmitter emit = (InstrEmitter)i.type->emit; + if (!i.type->emit || emit(*this, fn_, i)) { + // This printf is handy for sort/uniquify to find instructions. + //printf("unimplinstr %s\n", i.type->name); + + XELOGCPU("Unimplemented instr %.8X %.8X %s", + ia, i.code, i.type->name); + SpillRegisters(); + jit_insn_call_native( + fn_, + "XeInvalidInstruction", + global_exports_.XeInvalidInstruction, + global_export_signature_3_, + trace_args, XECOUNT(trace_args), + 0); + } + } + + // If we fall through, create the branch. + if (block->outgoing_type == FunctionBlock::kTargetNone) { + // BasicBlock* next_bb = GetNextBasicBlock(); + // XEASSERTNOTNULL(next_bb); + // b.CreateBr(next_bb); + } else if (block->outgoing_type == FunctionBlock::kTargetUnknown) { + // Hrm. + // TODO(benvanik): assert this doesn't occur - means a bad sdb run! + XELOGCPU("SDB function scan error in %.8X: bb %.8X has unknown exit", + symbol_->start_address, block->start_address); + jit_insn_return(fn_, NULL); + } + + // TODO(benvanik): finish up BB +} + +int LibjitEmitter::branch_to_block(uint32_t address) { + std::map::iterator it = bbs_.find(address); + return jit_insn_branch(fn_, &it->second); +} + +int LibjitEmitter::branch_to_block_if(uint32_t address, jit_value_t value) { + std::map::iterator it = bbs_.find(address); + return jit_insn_branch_if(fn_, value, &it->second); +} + +int LibjitEmitter::branch_to_block_if_not(uint32_t address, jit_value_t value) { + std::map::iterator it = bbs_.find(address); + return jit_insn_branch_if_not(fn_, value, &it->second); +} + +int LibjitEmitter::branch_to_return() { + return jit_insn_branch(fn_, &return_block_); +} + +int LibjitEmitter::branch_to_return_if(jit_value_t value) { + return jit_insn_branch_if(fn_, value, &return_block_); +} + +int LibjitEmitter::branch_to_return_if_not(jit_value_t value) { + return jit_insn_branch_if_not(fn_, value, &return_block_); +} + //BasicBlock* LibjitEmitter::GetNextBasicBlock() { // std::map::iterator it = bbs_.find( -// symbol_block_->start_address); +// fn_block_->start_address); // ++it; // if (it != bbs_.end()) { // return it->second; // } // return NULL; //} -// -//BasicBlock* LibjitEmitter::GetReturnBasicBlock() { -// return return_block_; -//} -//int LibjitEmitter::GenerateIndirectionBranch(uint32_t cia, Value* target, +//int LibjitEmitter::GenerateIndirectionBranch(uint32_t cia, jit_value_t target, // bool lk, bool likely_local) { // // This function is called by the control emitters when they know that an // // indirect branch is required. @@ -626,9 +613,9 @@ jit_function_t LibjitEmitter::fn() { // // Setup locals in the entry block. // b.SetInsertPoint(&fn_->getEntryBlock()); // locals_.indirection_target = b.CreateAlloca( -// b.getInt64Ty(), 0, "indirection_target"); +// jit_type_nint, 0, "indirection_target"); // locals_.indirection_cia = b.CreateAlloca( -// b.getInt64Ty(), 0, "indirection_cia"); +// jit_type_nint, 0, "indirection_cia"); // // external_indirection_block_ = BasicBlock::Create( // *context_, "external_indirection_block", fn_, return_block_); @@ -649,9 +636,9 @@ jit_function_t LibjitEmitter::fn() { // XEASSERT(!lk); // b.CreateStore(target, locals_.indirection_target); // b.CreateStore(b.getInt64(cia), locals_.indirection_cia); -// Value* symbol_ge_cmp = b.CreateICmpUGE(target, b.getInt64(symbol_->start_address)); -// Value* symbol_l_cmp = b.CreateICmpULT(target, b.getInt64(symbol_->end_address)); -// Value* symbol_target_cmp = b.CreateAnd(symbol_ge_cmp, symbol_l_cmp); +// jit_value_t symbol_ge_cmp = b.CreateICmpUGE(target, b.getInt64(symbol_->start_address)); +// jit_value_t symbol_l_cmp = b.CreateICmpULT(target, b.getInt64(symbol_->end_address)); +// jit_value_t symbol_target_cmp = b.CreateAnd(symbol_ge_cmp, symbol_l_cmp); // b.CreateCondBr(symbol_target_cmp, // internal_indirection_block_, external_indirection_block_); // return 0; @@ -672,7 +659,7 @@ jit_function_t LibjitEmitter::fn() { // SpillRegisters(); // // // TODO(benvanik): keep function pointer lookup local. -// Value* indirect_branch = gen_module_->getFunction("XeIndirectBranch"); +// jit_value_t indirect_branch = gen_module_->getFunction("XeIndirectBranch"); // b.CreateCall3(indirect_branch, // fn_->arg_begin(), // target, @@ -690,289 +677,280 @@ jit_function_t LibjitEmitter::fn() { // return 0; //} // -//Value* LibjitEmitter::LoadStateValue(uint32_t offset, Type* type, +//jit_value_t LibjitEmitter::LoadStateValue(uint32_t offset, jit_type_t type, // const char* name) { // IRBuilder<>& b = *builder_; // PointerType* pointerTy = PointerType::getUnqual(type); // Function::arg_iterator args = fn_->arg_begin(); -// Value* state_ptr = args; -// Value* address = b.CreateInBoundsGEP(state_ptr, b.getInt32(offset)); -// Value* ptr = b.CreatePointerCast(address, pointerTy); +// jit_value_t state_ptr = args; +// jit_value_t address = b.CreateInBoundsGEP(state_ptr, b.getInt32(offset)); +// jit_value_t ptr = b.CreatePointerCast(address, pointerTy); // return b.CreateLoad(ptr, name); //} // -//void LibjitEmitter::StoreStateValue(uint32_t offset, Type* type, -// Value* value) { +//void LibjitEmitter::StoreStateValue(uint32_t offset, jit_type_t type, +// jit_value_t value) { // IRBuilder<>& b = *builder_; // PointerType* pointerTy = PointerType::getUnqual(type); // Function::arg_iterator args = fn_->arg_begin(); -// Value* state_ptr = args; -// Value* address = b.CreateInBoundsGEP(state_ptr, b.getInt32(offset)); -// Value* ptr = b.CreatePointerCast(address, pointerTy); +// jit_value_t state_ptr = args; +// jit_value_t address = b.CreateInBoundsGEP(state_ptr, b.getInt32(offset)); +// jit_value_t ptr = b.CreatePointerCast(address, pointerTy); // b.CreateStore(value, ptr); //} -// -//void LibjitEmitter::SetupLocals() { -// IRBuilder<>& b = *builder_; -// -// uint64_t spr_t = access_bits_.spr; -// if (spr_t & 0x3) { -// locals_.xer = SetupLocal(b.getInt64Ty(), "xer"); -// } -// spr_t >>= 2; -// if (spr_t & 0x3) { -// locals_.lr = SetupLocal(b.getInt64Ty(), "lr"); -// } -// spr_t >>= 2; -// if (spr_t & 0x3) { -// locals_.ctr = SetupLocal(b.getInt64Ty(), "ctr"); -// } -// spr_t >>= 2; -// // TODO: FPCSR -// -// char name[32]; -// -// uint64_t cr_t = access_bits_.cr; -// for (int n = 0; n < 8; n++) { -// if (cr_t & 3) { -// xesnprintfa(name, XECOUNT(name), "cr%d", n); -// locals_.cr[n] = SetupLocal(b.getInt8Ty(), name); -// } -// cr_t >>= 2; -// } -// -// uint64_t gpr_t = access_bits_.gpr; -// for (int n = 0; n < 32; n++) { -// if (gpr_t & 3) { -// xesnprintfa(name, XECOUNT(name), "r%d", n); -// locals_.gpr[n] = SetupLocal(b.getInt64Ty(), name); -// } -// gpr_t >>= 2; -// } -// -// uint64_t fpr_t = access_bits_.fpr; -// for (int n = 0; n < 32; n++) { -// if (fpr_t & 3) { -// xesnprintfa(name, XECOUNT(name), "f%d", n); -// locals_.fpr[n] = SetupLocal(b.getDoubleTy(), name); -// } -// fpr_t >>= 2; -// } -//} -// -//Value* LibjitEmitter::SetupLocal(llvm::Type* type, const char* name) { -// IRBuilder<>& b = *builder_; -// // Insert into the entry block. -// PushInsertPoint(); -// b.SetInsertPoint(&fn_->getEntryBlock()); -// Value* v = b.CreateAlloca(type, 0, name); -// PopInsertPoint(); -// return v; -//} -// -//Value* LibjitEmitter::cia_value() { + +void LibjitEmitter::SetupLocals() { + uint64_t spr_t = access_bits_.spr; + if (spr_t & 0x3) { + locals_.xer = SetupLocal(jit_type_nint, "xer"); + } + spr_t >>= 2; + if (spr_t & 0x3) { + locals_.lr = SetupLocal(jit_type_nint, "lr"); + } + spr_t >>= 2; + if (spr_t & 0x3) { + locals_.ctr = SetupLocal(jit_type_nint, "ctr"); + } + spr_t >>= 2; + // TODO: FPCSR + + char name[32]; + + uint64_t cr_t = access_bits_.cr; + for (int n = 0; n < 8; n++) { + if (cr_t & 3) { + //xesnprintfa(name, XECOUNT(name), "cr%d", n); + locals_.cr[n] = SetupLocal(jit_type_ubyte, name); + } + cr_t >>= 2; + } + + uint64_t gpr_t = access_bits_.gpr; + for (int n = 0; n < 32; n++) { + if (gpr_t & 3) { + //xesnprintfa(name, XECOUNT(name), "r%d", n); + locals_.gpr[n] = SetupLocal(jit_type_nint, name); + } + gpr_t >>= 2; + } + + uint64_t fpr_t = access_bits_.fpr; + for (int n = 0; n < 32; n++) { + if (fpr_t & 3) { + //xesnprintfa(name, XECOUNT(name), "f%d", n); + locals_.fpr[n] = SetupLocal(jit_type_float64, name); + } + fpr_t >>= 2; + } +} + +jit_value_t LibjitEmitter::SetupLocal(jit_type_t type, const char* name) { + // Note that the value is created in the current block, but will be pushed + // up to function level if used in another block. + jit_value_t value = jit_value_create(fn_, type); + // TODO(benvanik): set a name? + return value; +} + +//jit_value_t LibjitEmitter::cia_value() { // return builder_->getInt32(cia_); //} -// -//void LibjitEmitter::FillRegisters() { -// // This updates all of the local register values from the state memory. -// // It should be called on function entry for initial setup and after any -// // calls that may modify the registers. -// -// // TODO(benvanik): use access flags to see if we need to do reads/writes. -// // Though LLVM may do a better job than we can, except across calls. -// -// IRBuilder<>& b = *builder_; -// -// if (locals_.xer) { -// b.CreateStore(LoadStateValue( -// offsetof(xe_ppc_state_t, xer), -// b.getInt64Ty()), locals_.xer); -// } -// -// if (locals_.lr) { -// b.CreateStore(LoadStateValue( -// offsetof(xe_ppc_state_t, lr), -// b.getInt64Ty()), locals_.lr); -// } -// -// if (locals_.ctr) { -// b.CreateStore(LoadStateValue( -// offsetof(xe_ppc_state_t, ctr), -// b.getInt64Ty()), locals_.ctr); -// } -// -// // Fill the split CR values by extracting each one from the CR. -// // This could probably be done faster via an extractvalues or something. -// // Perhaps we could also change it to be a vector<8*i8>. -// Value* cr = NULL; -// for (size_t n = 0; n < XECOUNT(locals_.cr); n++) { -// Value* cr_n = locals_.cr[n]; -// if (!cr_n) { -// continue; -// } -// if (!cr) { -// cr = LoadStateValue( -// offsetof(xe_ppc_state_t, cr), -// b.getInt64Ty()); -// } -// b.CreateStore( -// b.CreateTrunc(b.CreateAnd(b.CreateLShr(cr, (28 - n * 4)), 0xF), -// b.getInt8Ty()), cr_n); -// } -// -// for (size_t n = 0; n < XECOUNT(locals_.gpr); n++) { -// if (locals_.gpr[n]) { -// b.CreateStore(LoadStateValue( -// (uint32_t)offsetof(xe_ppc_state_t, r) + 8 * n, -// b.getInt64Ty()), locals_.gpr[n]); -// } -// } -// -// for (size_t n = 0; n < XECOUNT(locals_.fpr); n++) { -// if (locals_.fpr[n]) { -// b.CreateStore(LoadStateValue( -// (uint32_t)offsetof(xe_ppc_state_t, f) + 8 * n, -// b.getDoubleTy()), locals_.fpr[n]); -// } -// } -//} -// -//void LibjitEmitter::SpillRegisters() { -// // This flushes all local registers (if written) to the register bank and -// // resets their values. -// // -// // TODO(benvanik): only flush if actually required, or selective flushes. -// -// IRBuilder<>& b = *builder_; -// -// if (locals_.xer) { -// StoreStateValue( -// offsetof(xe_ppc_state_t, xer), -// b.getInt64Ty(), -// b.CreateLoad(locals_.xer)); -// } -// -// if (locals_.lr) { -// StoreStateValue( -// offsetof(xe_ppc_state_t, lr), -// b.getInt64Ty(), -// b.CreateLoad(locals_.lr)); -// } -// -// if (locals_.ctr) { -// StoreStateValue( -// offsetof(xe_ppc_state_t, ctr), -// b.getInt64Ty(), -// b.CreateLoad(locals_.ctr)); -// } -// -// // Stitch together all split CR values. -// // TODO(benvanik): don't flush across calls? -// Value* cr = NULL; -// for (size_t n = 0; n < XECOUNT(locals_.cr); n++) { -// Value* cr_n = locals_.cr[n]; -// if (!cr_n) { -// continue; -// } -// cr_n = b.CreateZExt(b.CreateLoad(cr_n), b.getInt64Ty()); -// if (!cr) { -// cr = b.CreateShl(cr_n, n * 4); -// } else { -// cr = b.CreateOr(cr, b.CreateShl(cr_n, n * 4)); -// } -// } -// if (cr) { -// StoreStateValue( -// offsetof(xe_ppc_state_t, cr), -// b.getInt64Ty(), -// cr); -// } -// -// for (uint32_t n = 0; n < XECOUNT(locals_.gpr); n++) { -// Value* v = locals_.gpr[n]; -// if (v) { -// StoreStateValue( -// offsetof(xe_ppc_state_t, r) + 8 * n, -// b.getInt64Ty(), -// b.CreateLoad(locals_.gpr[n])); -// } -// } -// -// for (uint32_t n = 0; n < XECOUNT(locals_.fpr); n++) { -// Value* v = locals_.fpr[n]; -// if (v) { -// StoreStateValue( -// offsetof(xe_ppc_state_t, f) + 8 * n, -// b.getDoubleTy(), -// b.CreateLoad(locals_.fpr[n])); -// } -// } -//} -// -//Value* LibjitEmitter::xer_value() { + +void LibjitEmitter::FillRegisters() { + // This updates all of the local register values from the state memory. + // It should be called on function entry for initial setup and after any + // calls that may modify the registers. + + // TODO(benvanik): use access flags to see if we need to do reads/writes. + + // if (locals_.xer) { + // b.CreateStore(LoadStateValue( + // offsetof(xe_ppc_state_t, xer), + // jit_type_nint), locals_.xer); + // } + + // if (locals_.lr) { + // b.CreateStore(LoadStateValue( + // offsetof(xe_ppc_state_t, lr), + // jit_type_nint), locals_.lr); + // } + + // if (locals_.ctr) { + // b.CreateStore(LoadStateValue( + // offsetof(xe_ppc_state_t, ctr), + // jit_type_nint), locals_.ctr); + // } + + // // Fill the split CR values by extracting each one from the CR. + // // This could probably be done faster via an extractvalues or something. + // // Perhaps we could also change it to be a vector<8*i8>. + // jit_value_t cr = NULL; + // for (size_t n = 0; n < XECOUNT(locals_.cr); n++) { + // jit_value_t cr_n = locals_.cr[n]; + // if (!cr_n) { + // continue; + // } + // if (!cr) { + // cr = LoadStateValue( + // offsetof(xe_ppc_state_t, cr), + // jit_type_nint); + // } + // b.CreateStore( + // b.CreateTrunc(b.CreateAnd(b.CreateLShr(cr, (28 - n * 4)), 0xF), + // b.getInt8Ty()), cr_n); + // } + + // for (size_t n = 0; n < XECOUNT(locals_.gpr); n++) { + // if (locals_.gpr[n]) { + // b.CreateStore(LoadStateValue( + // (uint32_t)offsetof(xe_ppc_state_t, r) + 8 * n, + // jit_type_nint), locals_.gpr[n]); + // } + // } + + // for (size_t n = 0; n < XECOUNT(locals_.fpr); n++) { + // if (locals_.fpr[n]) { + // b.CreateStore(LoadStateValue( + // (uint32_t)offsetof(xe_ppc_state_t, f) + 8 * n, + // jit_type_float64), locals_.fpr[n]); + // } + // } +} + +void LibjitEmitter::SpillRegisters() { + // This flushes all local registers (if written) to the register bank and + // resets their values. + + // TODO(benvanik): only flush if actually required, or selective flushes. + + // if (locals_.xer) { + // StoreStateValue( + // offsetof(xe_ppc_state_t, xer), + // jit_type_nint, + // b.CreateLoad(locals_.xer)); + // } + + // if (locals_.lr) { + // StoreStateValue( + // offsetof(xe_ppc_state_t, lr), + // jit_type_nint, + // b.CreateLoad(locals_.lr)); + // } + + // if (locals_.ctr) { + // StoreStateValue( + // offsetof(xe_ppc_state_t, ctr), + // jit_type_nint, + // b.CreateLoad(locals_.ctr)); + // } + + // // Stitch together all split CR values. + // // TODO(benvanik): don't flush across calls? + // jit_value_t cr = NULL; + // for (size_t n = 0; n < XECOUNT(locals_.cr); n++) { + // jit_value_t cr_n = locals_.cr[n]; + // if (!cr_n) { + // continue; + // } + // cr_n = b.CreateZExt(b.CreateLoad(cr_n), jit_type_nint); + // if (!cr) { + // cr = b.CreateShl(cr_n, n * 4); + // } else { + // cr = b.CreateOr(cr, b.CreateShl(cr_n, n * 4)); + // } + // } + // if (cr) { + // StoreStateValue( + // offsetof(xe_ppc_state_t, cr), + // jit_type_nint, + // cr); + // } + + // for (uint32_t n = 0; n < XECOUNT(locals_.gpr); n++) { + // jit_value_t v = locals_.gpr[n]; + // if (v) { + // StoreStateValue( + // offsetof(xe_ppc_state_t, r) + 8 * n, + // jit_type_nint, + // b.CreateLoad(locals_.gpr[n])); + // } + // } + + // for (uint32_t n = 0; n < XECOUNT(locals_.fpr); n++) { + // jit_value_t v = locals_.fpr[n]; + // if (v) { + // StoreStateValue( + // offsetof(xe_ppc_state_t, f) + 8 * n, + // jit_type_float64, + // b.CreateLoad(locals_.fpr[n])); + // } + // } +} + +//jit_value_t LibjitEmitter::xer_value() { // XEASSERTNOTNULL(locals_.xer); // IRBuilder<>& b = *builder_; // return b.CreateLoad(locals_.xer); //} // -//void LibjitEmitter::update_xer_value(Value* value) { +//void LibjitEmitter::update_xer_value(jit_value_t value) { // XEASSERTNOTNULL(locals_.xer); // IRBuilder<>& b = *builder_; // // // Extend to 64bits if needed. // if (!value->getType()->isIntegerTy(64)) { -// value = b.CreateZExt(value, b.getInt64Ty()); +// value = b.CreateZExt(value, jit_type_nint); // } // b.CreateStore(value, locals_.xer); //} // -//void LibjitEmitter::update_xer_with_overflow(Value* value) { +//void LibjitEmitter::update_xer_with_overflow(jit_value_t value) { // XEASSERTNOTNULL(locals_.xer); // IRBuilder<>& b = *builder_; // // // Expects a i1 indicating overflow. // // Trust the caller that if it's larger than that it's already truncated. // if (!value->getType()->isIntegerTy(64)) { -// value = b.CreateZExt(value, b.getInt64Ty()); +// value = b.CreateZExt(value, jit_type_nint); // } // -// Value* xer = xer_value(); +// jit_value_t xer = xer_value(); // xer = b.CreateAnd(xer, 0xFFFFFFFFBFFFFFFF); // clear bit 30 // xer = b.CreateOr(xer, b.CreateShl(value, 31)); // xer = b.CreateOr(xer, b.CreateShl(value, 30)); // b.CreateStore(xer, locals_.xer); //} // -//void LibjitEmitter::update_xer_with_carry(Value* value) { +//void LibjitEmitter::update_xer_with_carry(jit_value_t value) { // XEASSERTNOTNULL(locals_.xer); // IRBuilder<>& b = *builder_; // // // Expects a i1 indicating carry. // // Trust the caller that if it's larger than that it's already truncated. // if (!value->getType()->isIntegerTy(64)) { -// value = b.CreateZExt(value, b.getInt64Ty()); +// value = b.CreateZExt(value, jit_type_nint); // } // -// Value* xer = xer_value(); +// jit_value_t xer = xer_value(); // xer = b.CreateAnd(xer, 0xFFFFFFFFDFFFFFFF); // clear bit 29 // xer = b.CreateOr(xer, b.CreateShl(value, 29)); // b.CreateStore(xer, locals_.xer); //} // -//void LibjitEmitter::update_xer_with_overflow_and_carry(Value* value) { +//void LibjitEmitter::update_xer_with_overflow_and_carry(jit_value_t value) { // XEASSERTNOTNULL(locals_.xer); // IRBuilder<>& b = *builder_; // // // Expects a i1 indicating overflow. // // Trust the caller that if it's larger than that it's already truncated. // if (!value->getType()->isIntegerTy(64)) { -// value = b.CreateZExt(value, b.getInt64Ty()); +// value = b.CreateZExt(value, jit_type_nint); // } // // // This is effectively an update_xer_with_overflow followed by an // // update_xer_with_carry, but since the logic is largely the same share it. -// Value* xer = xer_value(); +// jit_value_t xer = xer_value(); // xer = b.CreateAnd(xer, 0xFFFFFFFF9FFFFFFF); // clear bit 30 & 29 // xer = b.CreateOr(xer, b.CreateShl(value, 31)); // xer = b.CreateOr(xer, b.CreateShl(value, 30)); @@ -980,52 +958,52 @@ jit_function_t LibjitEmitter::fn() { // b.CreateStore(xer, locals_.xer); //} // -//Value* LibjitEmitter::lr_value() { +//jit_value_t LibjitEmitter::lr_value() { // XEASSERTNOTNULL(locals_.lr); // IRBuilder<>& b = *builder_; // return b.CreateLoad(locals_.lr); //} // -//void LibjitEmitter::update_lr_value(Value* value) { +//void LibjitEmitter::update_lr_value(jit_value_t value) { // XEASSERTNOTNULL(locals_.lr); // IRBuilder<>& b = *builder_; // // // Extend to 64bits if needed. // if (!value->getType()->isIntegerTy(64)) { -// value = b.CreateZExt(value, b.getInt64Ty()); +// value = b.CreateZExt(value, jit_type_nint); // } // b.CreateStore(value, locals_.lr); //} // -//Value* LibjitEmitter::ctr_value() { +//jit_value_t LibjitEmitter::ctr_value() { // XEASSERTNOTNULL(locals_.ctr); // IRBuilder<>& b = *builder_; // // return b.CreateLoad(locals_.ctr); //} // -//void LibjitEmitter::update_ctr_value(Value* value) { +//void LibjitEmitter::update_ctr_value(jit_value_t value) { // XEASSERTNOTNULL(locals_.ctr); // IRBuilder<>& b = *builder_; // // // Extend to 64bits if needed. // if (!value->getType()->isIntegerTy(64)) { -// value = b.CreateZExt(value, b.getInt64Ty()); +// value = b.CreateZExt(value, jit_type_nint); // } // b.CreateStore(value, locals_.ctr); //} // -//Value* LibjitEmitter::cr_value(uint32_t n) { +//jit_value_t LibjitEmitter::cr_value(uint32_t n) { // XEASSERT(n >= 0 && n < 8); // XEASSERTNOTNULL(locals_.cr[n]); // IRBuilder<>& b = *builder_; // -// Value* v = b.CreateLoad(locals_.cr[n]); -// v = b.CreateZExt(v, b.getInt64Ty()); +// jit_value_t v = b.CreateLoad(locals_.cr[n]); +// v = b.CreateZExt(v, jit_type_nint); // return v; //} // -//void LibjitEmitter::update_cr_value(uint32_t n, Value* value) { +//void LibjitEmitter::update_cr_value(uint32_t n, jit_value_t value) { // XEASSERT(n >= 0 && n < 8); // XEASSERTNOTNULL(locals_.cr[n]); // IRBuilder<>& b = *builder_; @@ -1040,7 +1018,7 @@ jit_function_t LibjitEmitter::fn() { //} // //void LibjitEmitter::update_cr_with_cond( -// uint32_t n, Value* lhs, Value* rhs, bool is_signed) { +// uint32_t n, jit_value_t lhs, jit_value_t rhs, bool is_signed) { // IRBuilder<>& b = *builder_; // // // bit0 = RA < RB @@ -1051,19 +1029,19 @@ jit_function_t LibjitEmitter::fn() { // // TODO(benvanik): inline this using the x86 cmp instruction - this prevents // // the need for a lot of the compares and ensures we lower to the best // // possible x86. -// // Value* cmp = InlineAsm::get( +// // jit_value_t cmp = InlineAsm::get( // // FunctionType::get(), // // "cmp $0, $1 \n" // // "mov from compare registers \n", // // "r,r", ?? // // true); // -// Value* is_lt = is_signed ? +// jit_value_t is_lt = is_signed ? // b.CreateICmpSLT(lhs, rhs) : b.CreateICmpULT(lhs, rhs); -// Value* is_gt = is_signed ? +// jit_value_t is_gt = is_signed ? // b.CreateICmpSGT(lhs, rhs) : b.CreateICmpUGT(lhs, rhs); -// Value* cp = b.CreateSelect(is_gt, b.getInt8(1 << 1), b.getInt8(1 << 2)); -// Value* c = b.CreateSelect(is_lt, b.getInt8(1 << 0), cp); +// jit_value_t cp = b.CreateSelect(is_gt, b.getInt8(1 << 1), b.getInt8(1 << 2)); +// jit_value_t c = b.CreateSelect(is_lt, b.getInt8(1 << 0), cp); // // // TODO(benvanik): set bit 4 to XER[SO] // @@ -1071,7 +1049,7 @@ jit_function_t LibjitEmitter::fn() { // update_cr_value(n, c); //} // -//Value* LibjitEmitter::gpr_value(uint32_t n) { +//jit_value_t LibjitEmitter::gpr_value(uint32_t n) { // XEASSERT(n >= 0 && n < 32); // XEASSERTNOTNULL(locals_.gpr[n]); // IRBuilder<>& b = *builder_; @@ -1086,7 +1064,7 @@ jit_function_t LibjitEmitter::fn() { // return b.CreateLoad(locals_.gpr[n]); //} // -//void LibjitEmitter::update_gpr_value(uint32_t n, Value* value) { +//void LibjitEmitter::update_gpr_value(uint32_t n, jit_value_t value) { // XEASSERT(n >= 0 && n < 32); // XEASSERTNOTNULL(locals_.gpr[n]); // IRBuilder<>& b = *builder_; @@ -1099,33 +1077,33 @@ jit_function_t LibjitEmitter::fn() { // // // Extend to 64bits if needed. // if (!value->getType()->isIntegerTy(64)) { -// value = b.CreateZExt(value, b.getInt64Ty()); +// value = b.CreateZExt(value, jit_type_nint); // } // // b.CreateStore(value, locals_.gpr[n]); //} // -//Value* LibjitEmitter::fpr_value(uint32_t n) { +//jit_value_t LibjitEmitter::fpr_value(uint32_t n) { // XEASSERT(n >= 0 && n < 32); // XEASSERTNOTNULL(locals_.fpr[n]); // IRBuilder<>& b = *builder_; // return b.CreateLoad(locals_.fpr[n]); //} // -//void LibjitEmitter::update_fpr_value(uint32_t n, Value* value) { +//void LibjitEmitter::update_fpr_value(uint32_t n, jit_value_t value) { // XEASSERT(n >= 0 && n < 32); // XEASSERTNOTNULL(locals_.fpr[n]); // IRBuilder<>& b = *builder_; -// value = b.CreateFPExtOrFPTrunc(value, b.getDoubleTy()); +// value = b.CreateFPExtOrFPTrunc(value, jit_type_float64); // b.CreateStore(value, locals_.fpr[n]); //} // -//Value* LibjitEmitter::GetMembase() { -// Value* v = gen_module_->getGlobalVariable("xe_memory_base"); +//jit_value_t LibjitEmitter::GetMembase() { +// jit_value_t v = gen_module_->getGlobalVariable("xe_memory_base"); // return builder_->CreateLoad(v); //} // -//Value* LibjitEmitter::GetMemoryAddress(uint32_t cia, Value* addr) { +//jit_value_t LibjitEmitter::GetMemoryAddress(uint32_t cia, jit_value_t addr) { // IRBuilder<>& b = *builder_; // // // Input address is always in 32-bit space. @@ -1137,11 +1115,11 @@ jit_function_t LibjitEmitter::fn() { // BasicBlock* valid_bb = BasicBlock::Create(*context_, "", fn_); // // // The heap starts at 0x1000 - if we write below that we're boned. -// Value* gt = b.CreateICmpUGE(addr, b.getInt64(0x00001000)); +// jit_value_t gt = b.CreateICmpUGE(addr, b.getInt64(0x00001000)); // b.CreateCondBr(gt, valid_bb, invalid_bb); // // b.SetInsertPoint(invalid_bb); -// Value* access_violation = gen_module_->getFunction("XeAccessViolation"); +// jit_value_t access_violation = gen_module_->getFunction("XeAccessViolation"); // SpillRegisters(); // b.CreateCall3(access_violation, // fn_->arg_begin(), @@ -1156,26 +1134,24 @@ jit_function_t LibjitEmitter::fn() { // return b.CreateInBoundsGEP(GetMembase(), addr); //} // -//Value* LibjitEmitter::ReadMemory( -// uint32_t cia, Value* addr, uint32_t size, bool acquire) { -// IRBuilder<>& b = *builder_; -// -// Type* dataTy = NULL; +//jit_value_t LibjitEmitter::ReadMemory( +// uint32_t cia, jit_value_t addr, uint32_t size, bool acquire) { +// jit_type_t dataTy = NULL; // bool needs_swap = false; // switch (size) { // case 1: -// dataTy = b.getInt8Ty(); +// dataTy = jit_type_ubyte; // break; // case 2: -// dataTy = b.getInt16Ty(); +// dataTy = jit_type_ushort; // needs_swap = true; // break; // case 4: -// dataTy = b.getInt32Ty(); +// dataTy = jit_type_uint; // needs_swap = true; // break; // case 8: -// dataTy = b.getInt64Ty(); +// dataTy = jit_type_ulong; // needs_swap = true; // break; // default: @@ -1184,15 +1160,15 @@ jit_function_t LibjitEmitter::fn() { // } // PointerType* pointerTy = PointerType::getUnqual(dataTy); // -// Value* address = GetMemoryAddress(cia, addr); -// Value* ptr = b.CreatePointerCast(address, pointerTy); +// jit_value_t address = GetMemoryAddress(cia, addr); +// jit_value_t ptr = b.CreatePointerCast(address, pointerTy); // LoadInst* load_value = b.CreateLoad(ptr); // if (acquire) { // load_value->setAlignment(size); // load_value->setVolatile(true); // load_value->setAtomic(Acquire); // } -// Value* value = load_value; +// jit_value_t value = load_value; // // // Swap after loading. // // TODO(benvanik): find a way to avoid this! @@ -1206,25 +1182,25 @@ jit_function_t LibjitEmitter::fn() { //} // //void LibjitEmitter::WriteMemory( -// uint32_t cia, Value* addr, uint32_t size, Value* value, bool release) { +// uint32_t cia, jit_value_t addr, uint32_t size, jit_value_t value, bool release) { // IRBuilder<>& b = *builder_; // -// Type* dataTy = NULL; +// jit_type_t dataTy = NULL; // bool needs_swap = false; // switch (size) { // case 1: -// dataTy = b.getInt8Ty(); +// dataTy = jit_type_ubyte; // break; // case 2: -// dataTy = b.getInt16Ty(); +// dataTy = jit_type_ushort; // needs_swap = true; // break; // case 4: -// dataTy = b.getInt32Ty(); +// dataTy = jit_type_uint; // needs_swap = true; // break; // case 8: -// dataTy = b.getInt64Ty(); +// dataTy = jit_type_ulong; // needs_swap = true; // break; // default: @@ -1233,8 +1209,8 @@ jit_function_t LibjitEmitter::fn() { // } // PointerType* pointerTy = PointerType::getUnqual(dataTy); // -// Value* address = GetMemoryAddress(cia, addr); -// Value* ptr = b.CreatePointerCast(address, pointerTy); +// jit_value_t address = GetMemoryAddress(cia, addr); +// jit_value_t ptr = b.CreatePointerCast(address, pointerTy); // // // Truncate, if required. // if (value->getType() != dataTy) { diff --git a/src/xenia/cpu/libjit/libjit_emitter.h b/src/xenia/cpu/libjit/libjit_emitter.h index fd53c1d0b..af8598a94 100644 --- a/src/xenia/cpu/libjit/libjit_emitter.h +++ b/src/xenia/cpu/libjit/libjit_emitter.h @@ -36,13 +36,12 @@ public: jit_function_t fn(); sdb::FunctionBlock* fn_block(); - void PushInsertPoint(); - void PopInsertPoint(); - - void GenerateBasicBlocks(); -// llvm::BasicBlock* GetBasicBlock(uint32_t address); -// llvm::BasicBlock* GetNextBasicBlock(); -// llvm::BasicBlock* GetReturnBasicBlock(); + int branch_to_block(uint32_t address); + int branch_to_block_if(uint32_t address, jit_value_t value); + int branch_to_block_if_not(uint32_t address, jit_value_t value); + int branch_to_return(); + int branch_to_return_if(jit_value_t value); + int branch_to_return_if_not(jit_value_t value); int GenerateIndirectionBranch(uint32_t cia, jit_value_t target, bool lk, bool likely_local); @@ -92,6 +91,7 @@ private: int MakePresentImportFunction(); int MakeMissingImportFunction(); + void GenerateBasicBlocks(); void GenerateSharedBlocks(); int PrepareBasicBlock(sdb::FunctionBlock* block); void GenerateBasicBlock(sdb::FunctionBlock* block); @@ -109,15 +109,11 @@ private: sdb::FunctionSymbol* symbol_; jit_function_t fn_; sdb::FunctionBlock* fn_block_; - // llvm::BasicBlock* return_block_; - // llvm::BasicBlock* internal_indirection_block_; - // llvm::BasicBlock* external_indirection_block_; - // llvm::BasicBlock* bb_; + jit_label_t return_block_; + jit_label_t internal_indirection_block_; + jit_label_t external_indirection_block_; - // std::vector > - // insert_points_; - - //std::map bbs_; + std::map bbs_; // Address of the instruction being generated. uint32_t cia_; diff --git a/src/xenia/cpu/ppc/instr.cc b/src/xenia/cpu/ppc/instr.cc index 79e92d10d..36b125d7d 100644 --- a/src/xenia/cpu/ppc/instr.cc +++ b/src/xenia/cpu/ppc/instr.cc @@ -292,7 +292,7 @@ void InstrDisasm::AddSImmOperand(uint64_t value, size_t width, o.type = InstrOperand::kImmediate; o.imm.is_signed = true; o.imm.value = value; - o.imm.width = value; + o.imm.width = width; o.display = display; operands.push_back(o); } @@ -303,7 +303,7 @@ void InstrDisasm::AddUImmOperand(uint64_t value, size_t width, o.type = InstrOperand::kImmediate; o.imm.is_signed = false; o.imm.value = value; - o.imm.width = value; + o.imm.width = width; o.display = display; operands.push_back(o); }