Adding some ALU instructions.

This commit is contained in:
Ben Vanik 2013-05-24 14:21:39 -07:00
parent 8965caa833
commit e724fe3e60
4 changed files with 428 additions and 396 deletions

View File

@ -65,6 +65,9 @@ static inline int32_t XEEXTS16(uint32_t v) {
static inline int32_t XEEXTS26(uint32_t v) { static inline int32_t XEEXTS26(uint32_t v) {
return v & 0x02000000 ? (int32_t)v | 0xFC000000 : (int32_t)(v); return v & 0x02000000 ? (int32_t)v | 0xFC000000 : (int32_t)(v);
} }
static inline uint32_t XEEXTZ16(uint32_t v) {
return (uint32_t)((uint16_t)v);
}
static inline uint64_t XEMASK(uint32_t mstart, uint32_t mstop) { static inline uint64_t XEMASK(uint32_t mstart, uint32_t mstop) {
// if mstart ≤ mstop then // if mstart ≤ mstop then
// mask[mstart:mstop] = ones // mask[mstart:mstop] = ones

File diff suppressed because it is too large Load Diff

View File

@ -1326,45 +1326,56 @@ void X64Emitter::update_cr_value(uint32_t n, GpVar& value) {
} }
} }
#if 0 void X64Emitter::update_cr_with_cond(uint32_t n, GpVar& lhs) {
void X64Emitter::update_cr_with_cond( X86Compiler& c = compiler_;
uint32_t n, GpVar& lhs, GpVar& rhs, bool is_signed) { // bit0 = RA < 0
// bit1 = RA > 0
// bit2 = RA = 0
// bit3 = XER[SO]
// Compare and set bits.
GpVar v_l(c.newGpVar());
GpVar v_g(c.newGpVar());
GpVar v_e(c.newGpVar());
c.cmp(lhs, imm(0));
c.setl(v_l);
c.setg(v_g);
c.sete(v_e);
GpVar v(c.newGpVar());
c.shl(v_g, imm(1));
c.shl(v_e, imm(2));
c.or_(v, v_l);
c.or_(v, v_g);
c.or_(v, v_e);
// TODO(benvanik): set bit 4 to XER[SO]
// c.seto?
// Insert the 4 bits into their location in the CR.
update_cr_value(n, v);
}
void X64Emitter::update_cr_with_cond(uint32_t n, GpVar& lhs, GpVar& rhs) {
X86Compiler& c = compiler_; X86Compiler& c = compiler_;
// bit0 = RA < RB // bit0 = RA < RB
// bit1 = RA > RB // bit1 = RA > RB
// bit2 = RA = RB // bit2 = RA = RB
// bit3 = XER[SO] // bit3 = XER[SO]
// TODO(benvanik): inline this using the x86 cmp instruction - this prevents // Compare and set bits.
// the need for a lot of the compares and ensures we lower to the best c.cmp(lhs, rhs);
// possible x86. GpVar v_l(c.newGpVar()); c.setl(v_l);
// GpVar& cmp = InlineAsm::get( GpVar v_g(c.newGpVar()); c.setg(v_g); c.shl(v_g, imm(1));
// FunctionType::get(), GpVar v_e(c.newGpVar()); c.sete(v_e); c.shl(v_e, imm(2));
// "cmp $0, $1 \n" GpVar v(c.newGpVar());
// "mov from compare registers \n", c.or_(v, v_l); c.or_(v, v_g); c.or_(v, v_e);
// "r,r", ??
// true);
// Convert input signs, if needed.
if (is_signed) {
lhs = make_signed(lhs);
rhs = make_signed(rhs);
} else {
lhs = make_unsigned(lhs);
rhs = make_unsigned(rhs);
}
GpVar& c = jit_insn_lt(fn_, lhs, rhs);
c = jit_insn_or(fn_, c,
jit_insn_shl(fn_, jit_insn_gt(fn_, lhs, rhs), get_uint32(1)));
c = jit_insn_or(fn_, c,
jit_insn_shl(fn_, jit_insn_eq(fn_, lhs, rhs), get_uint32(2)));
// TODO(benvanik): set bit 4 to XER[SO] // TODO(benvanik): set bit 4 to XER[SO]
// c.seto?
// Insert the 4 bits into their location in the CR. // Insert the 4 bits into their location in the CR.
update_cr_value(n, c); update_cr_value(n, v);
} }
#endif
GpVar X64Emitter::gpr_value(uint32_t n) { GpVar X64Emitter::gpr_value(uint32_t n) {
X86Compiler& c = compiler_; X86Compiler& c = compiler_;

View File

@ -76,8 +76,8 @@ public:
AsmJit::GpVar cr_value(uint32_t n); AsmJit::GpVar cr_value(uint32_t n);
void update_cr_value(uint32_t n, AsmJit::GpVar& value); void update_cr_value(uint32_t n, AsmJit::GpVar& value);
void update_cr_with_cond(uint32_t n, AsmJit::GpVar& lhs, AsmJit::GpVar& rhs, void update_cr_with_cond(uint32_t n, AsmJit::GpVar& lhs);
bool is_signed); void update_cr_with_cond(uint32_t n, AsmJit::GpVar& lhs, AsmJit::GpVar& rhs);
AsmJit::GpVar gpr_value(uint32_t n); AsmJit::GpVar gpr_value(uint32_t n);
void update_gpr_value(uint32_t n, AsmJit::GpVar& value); void update_gpr_value(uint32_t n, AsmJit::GpVar& value);