JIT (ARM): Fix for transformers 32bit JIT, corrects shifts in 64bit jit on non condition shifts

- Special thanks to @byte4byte for these fixes.
This commit is contained in:
rogerman 2022-04-28 10:02:22 -07:00
parent a276d8c29c
commit ba630ee278
2 changed files with 27 additions and 9 deletions

View File

@ -280,12 +280,26 @@ static void emit_asr64(t_bytes *out, int reg, int num)
static void emit_asr_reg(t_bytes *out, int reg, int nreg) { static void emit_asr_reg(t_bytes *out, int reg, int nreg) {
int done=genlabel(); int done=genlabel();
int setb=genlabel();
emit_andimm(out, nreg, 0xff, nreg);
emit_cmpimm(out, nreg, 0); emit_cmpimm(out, nreg, 0);
emit_branch_label(out, done, 0); // eq 0 emit_branch_label(out, done, 0); // eq 0
emit_cmpimm(out, nreg, 32);
emit_branch_label(out, setb, 10); // greater than or equal to 32
output_w32(out, 0x1ac02800|nreg<<16|reg<<5|reg); // do shift output_w32(out, 0x1ac02800|nreg<<16|reg<<5|reg); // do shift
emit_branch_label(out, done, 0xE);
emit_label(out, (int)setb);
emit_movimm(out, 1<<31, 22);
emit_test(out, reg, 22); // test BIT31(reg 22) of original reg 20
emit_setnz(out, reg);
emit_movimm(out, 0xFFFFFFFF, 22);
emit_mul(out, reg, 22);
emit_label(out, (int)done); emit_label(out, (int)done);
} }
@ -313,6 +327,8 @@ static void emit_lsl_reg(t_bytes *out, int reg, int nreg) {
int setb=genlabel(); int setb=genlabel();
int done=genlabel(); int done=genlabel();
emit_andimm(out, nreg, 0xff, nreg);
emit_cmpimm(out, nreg, 32); emit_cmpimm(out, nreg, 32);
emit_branch_label(out, setb, 10); // greater than or equal to 32 emit_branch_label(out, setb, 10); // greater than or equal to 32
@ -338,6 +354,8 @@ static void emit_lsr_reg(t_bytes *out, int reg, int nreg)
int setb=genlabel(); int setb=genlabel();
int done=genlabel(); int done=genlabel();
emit_andimm(out, nreg, 0xff, nreg);
emit_cmpimm(out, nreg, 32); emit_cmpimm(out, nreg, 32);
emit_branch_label(out, setb, 10); // greater than or equal to 32 emit_branch_label(out, setb, 10); // greater than or equal to 32
@ -355,6 +373,8 @@ static void emit_ror_reg(t_bytes *out, int reg, int nreg) {
int done=genlabel(); int done=genlabel();
emit_andimm(out, nreg, 0xff, nreg);
emit_cmpimm(out, nreg, 0); emit_cmpimm(out, nreg, 0);
emit_branch_label(out, done, 0); // 0 emit_branch_label(out, done, 0); // 0
emit_andsimm(out, nreg, 0x1F, nreg); emit_andsimm(out, nreg, 0x1F, nreg);
@ -391,10 +411,6 @@ static void emit_rrxs(t_bytes *out, int reg, int n) {
emit_ror_reg(out, reg, SHIFT_REG); emit_ror_reg(out, reg, SHIFT_REG);
emit_andimm(out, reg, 0x7fffffff, reg); emit_andimm(out, reg, 0x7fffffff, reg);
emit_or(out, reg, 13, reg); emit_or(out, reg, 13, reg);
//emit_mov(out, 14, 5);
//emit_movimm(out, n, SHIFT_REG);
//emit_rrxs_reg(out, reg, SHIFT_REG);
} }
static void emit_lsls_reg(t_bytes *out, int reg, int nreg) { static void emit_lsls_reg(t_bytes *out, int reg, int nreg) {

View File

@ -512,20 +512,22 @@ static void emit_smultb(t_bytes *out, u_int rs1, u_int rs2) {
static void emit_smultt(t_bytes *out, u_int rs1, u_int rs2) { static void emit_smultt(t_bytes *out, u_int rs1, u_int rs2) {
output_w32(out, 0xE16000E0|(rs1<<16)|(rs2<<8)|rs1); output_w32(out, 0xE16000E0|(rs1<<16)|(rs2<<8)|rs1);
} }
static void emit_smulwt(t_bytes *out, u_int rs1, u_int rs2) { static void emit_smulwt(t_bytes *out, u_int rs1, u_int rs2) {
output_w32(out, 0xE12000E0|(rs1<<16)|(rs2<<8)|rs1); output_w32(out, 0xE12000E0|(rs1<<16)|(rs1<<8)|rs2);
} }
static void emit_smulwb(t_bytes *out, u_int rs1, u_int rs2) { static void emit_smulwb(t_bytes *out, u_int rs1, u_int rs2) {
output_w32(out, 0xE12000A0|(rs1<<16)|(rs2<<8)|rs1); output_w32(out, 0xE12000A0|(rs1<<16)|(rs1<<8)|rs2);
} }
static void emit_smlawb(t_bytes *out, u_int hi, u_int lo, u_int rs1, u_int rs2) static void emit_smlawb(t_bytes *out, u_int hi, u_int lo, u_int rs1, u_int rs2)
{ {
output_w32(out, 0xE1200080|(hi<<16)|(lo<<12)|(rs2<<8)|rs1); output_w32(out, 0xE1200080|(hi<<16)|(lo<<12)|(rs1<<8)|rs2);
} }
static void emit_smlawt(t_bytes *out, u_int hi, u_int lo, u_int rs1, u_int rs2) static void emit_smlawt(t_bytes *out, u_int hi, u_int lo, u_int rs1, u_int rs2)
{ {
output_w32(out, 0xE12000C0|(hi<<16)|(lo<<12)|(rs2<<8)|rs1); output_w32(out, 0xE12000C0|(hi<<16)|(lo<<12)|(rs1<<8)|rs2);
} }
static void emit_smlabb(t_bytes *out, u_int hi, u_int lo, u_int rs1, u_int rs2) static void emit_smlabb(t_bytes *out, u_int hi, u_int lo, u_int rs1, u_int rs2)