Fixed error in codegen for drol/dror opcodes in the x86 back-end.

Re-implemented misaligned memory handling in the RSP DRC as before.
This commit is contained in:
Aaron Giles 2009-12-30 06:19:08 +00:00
parent 09d0cb8e12
commit 31c7c2c219
2 changed files with 117 additions and 134 deletions

View File

@ -2896,32 +2896,33 @@ static void emit_rol_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UIN
else else
{ {
emit_link skip1, skip2; emit_link skip1, skip2;
emit_mov_m32_r32(dst, MBD(REG_ESP, -8), REG_EBX); // mov [esp-8],ebx int tempreg = REG_EAX;
// emit_mov_m32_r32(dst, MBD(REG_ESP, -8), tempreg); // mov [esp-8],ebx
emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param
emit_test_r32_imm(dst, REG_ECX, 0x20); // test ecx,0x20 emit_test_r32_imm(dst, REG_ECX, 0x20); // test ecx,0x20
emit_jcc_short_link(dst, COND_Z, &skip1); // jz skip1 emit_jcc_short_link(dst, COND_Z, &skip1); // jz skip1
if (inst->flags != 0) if (inst->flags != 0)
{ {
emit_sub_r32_imm(dst, REG_ECX, 31); // sub ecx,31 emit_sub_r32_imm(dst, REG_ECX, 31); // sub ecx,31
emit_mov_r32_r32(dst, REG_EBX, reglo); // mov ebx,reglo emit_mov_r32_r32(dst, tempreg, reglo); // mov ebx,reglo
emit_shld_r32_r32_imm(dst, reglo, reghi, 31); // shld reglo,reghi,31 emit_shld_r32_r32_imm(dst, reglo, reghi, 31); // shld reglo,reghi,31
emit_shld_r32_r32_imm(dst, reghi, REG_EBX, 31); // shld reghi,ebx,31 emit_shld_r32_r32_imm(dst, reghi, tempreg, 31); // shld reghi,ebx,31
emit_test_r32_imm(dst, REG_ECX, 0x20); // test ecx,0x20 emit_test_r32_imm(dst, REG_ECX, 0x20); // test ecx,0x20
emit_jcc_short_link(dst, COND_Z, &skip2); // jz skip2 emit_jcc_short_link(dst, COND_Z, &skip2); // jz skip2
emit_sub_r32_imm(dst, REG_ECX, 31); // sub ecx,31 emit_sub_r32_imm(dst, REG_ECX, 31); // sub ecx,31
emit_mov_r32_r32(dst, REG_EBX, reglo); // mov ebx,reglo emit_mov_r32_r32(dst, tempreg, reglo); // mov ebx,reglo
emit_shld_r32_r32_imm(dst, reglo, reghi, 31); // shld reglo,reghi,31 emit_shld_r32_r32_imm(dst, reglo, reghi, 31); // shld reglo,reghi,31
emit_shld_r32_r32_imm(dst, reghi, REG_EBX, 31); // shld reghi,ebx,31 emit_shld_r32_r32_imm(dst, reghi, tempreg, 31); // shld reghi,ebx,31
track_resolve_link(drcbe, dst, &skip2); // skip2: track_resolve_link(drcbe, dst, &skip2); // skip2:
} }
else else
emit_xchg_r32_r32(dst, reghi, reglo); // xchg reghi,reglo emit_xchg_r32_r32(dst, reghi, reglo); // xchg reghi,reglo
track_resolve_link(drcbe, dst, &skip1); // skip1: track_resolve_link(drcbe, dst, &skip1); // skip1:
emit_mov_r32_r32(dst, REG_EBX, reglo); // mov ebx,reglo emit_mov_r32_r32(dst, tempreg, reglo); // mov ebx,reglo
emit_shld_r32_r32_cl(dst, reglo, reghi); // shld reglo,reghi,cl emit_shld_r32_r32_cl(dst, reglo, reghi); // shld reglo,reghi,cl
if (saveflags) emit_pushf(dst); // pushf if (saveflags) emit_pushf(dst); // pushf
emit_shld_r32_r32_cl(dst, reghi, REG_EBX); // shld reghi,ebx,cl emit_shld_r32_r32_cl(dst, reghi, tempreg); // shld reghi,ebx,cl
emit_mov_r32_m32(dst, REG_EBX, MBD(REG_ESP, saveflags ? -4 : -8)); // mov ebx,[esp-8] // emit_mov_r32_m32(dst, tempreg, MBD(REG_ESP, saveflags ? -4 : -8)); // mov ebx,[esp-8]
} }
if (saveflags) if (saveflags)
emit_combine_z_flags(dst); emit_combine_z_flags(dst);
@ -2970,32 +2971,33 @@ static void emit_ror_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UIN
else else
{ {
emit_link skip1, skip2; emit_link skip1, skip2;
emit_mov_m32_r32(dst, MBD(REG_ESP, -8), REG_EBX); // mov [esp-8],ebx int tempreg = REG_EAX;
// emit_mov_m32_r32(dst, MBD(REG_ESP, -8), tempreg); // mov [esp-8],ebx
emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param
emit_test_r32_imm(dst, REG_ECX, 0x20); // test ecx,0x20 emit_test_r32_imm(dst, REG_ECX, 0x20); // test ecx,0x20
emit_jcc_short_link(dst, COND_Z, &skip1); // jz skip1 emit_jcc_short_link(dst, COND_Z, &skip1); // jz skip1
if (inst->flags != 0) if (inst->flags != 0)
{ {
emit_sub_r32_imm(dst, REG_ECX, 31); // sub ecx,31 emit_sub_r32_imm(dst, REG_ECX, 31); // sub ecx,31
emit_mov_r32_r32(dst, REG_EBX, reglo); // mov ebx,reglo emit_mov_r32_r32(dst, tempreg, reglo); // mov ebx,reglo
emit_shrd_r32_r32_imm(dst, reglo, reghi, 31); // shrd reglo,reghi,31 emit_shrd_r32_r32_imm(dst, reglo, reghi, 31); // shrd reglo,reghi,31
emit_shrd_r32_r32_imm(dst, reghi, REG_EBX, 31); // shrd reghi,ebx,31 emit_shrd_r32_r32_imm(dst, reghi, tempreg, 31); // shrd reghi,ebx,31
emit_test_r32_imm(dst, REG_ECX, 0x20); // test ecx,0x20 emit_test_r32_imm(dst, REG_ECX, 0x20); // test ecx,0x20
emit_jcc_short_link(dst, COND_Z, &skip2); // jz skip2 emit_jcc_short_link(dst, COND_Z, &skip2); // jz skip2
emit_sub_r32_imm(dst, REG_ECX, 31); // sub ecx,31 emit_sub_r32_imm(dst, REG_ECX, 31); // sub ecx,31
emit_mov_r32_r32(dst, REG_EBX, reglo); // mov ebx,reglo emit_mov_r32_r32(dst, tempreg, reglo); // mov ebx,reglo
emit_shrd_r32_r32_imm(dst, reglo, reghi, 31); // shrd reglo,reghi,31 emit_shrd_r32_r32_imm(dst, reglo, reghi, 31); // shrd reglo,reghi,31
emit_shrd_r32_r32_imm(dst, reghi, REG_EBX, 31); // shrd reghi,ebx,31 emit_shrd_r32_r32_imm(dst, reghi, tempreg, 31); // shrd reghi,ebx,31
track_resolve_link(drcbe, dst, &skip2); // skip2: track_resolve_link(drcbe, dst, &skip2); // skip2:
} }
else else
emit_xchg_r32_r32(dst, reghi, reglo); // xchg reghi,reglo emit_xchg_r32_r32(dst, reghi, reglo); // xchg reghi,reglo
track_resolve_link(drcbe, dst, &skip1); // skip1: track_resolve_link(drcbe, dst, &skip1); // skip1:
emit_mov_r32_r32(dst, REG_EBX, reglo); // mov ebx,reglo emit_mov_r32_r32(dst, tempreg, reglo); // mov ebx,reglo
emit_shrd_r32_r32_cl(dst, reglo, reghi); // shrd reglo,reghi,cl emit_shrd_r32_r32_cl(dst, reglo, reghi); // shrd reglo,reghi,cl
if (saveflags) emit_pushf(dst); // pushf if (saveflags) emit_pushf(dst); // pushf
emit_shrd_r32_r32_cl(dst, reghi, REG_EBX); // shrd reghi,ebx,cl emit_shrd_r32_r32_cl(dst, reghi, tempreg); // shrd reghi,ebx,cl
emit_mov_r32_m32(dst, REG_EBX, MBD(REG_ESP, saveflags ? -4 : -8)); // mov ebx,[esp-8] // emit_mov_r32_m32(dst, tempreg, MBD(REG_ESP, saveflags ? -4 : -8)); // mov ebx,[esp-8]
} }
if (saveflags) if (saveflags)
emit_combine_z_flags(dst); emit_combine_z_flags(dst);
@ -4863,27 +4865,28 @@ static x86code *op_rolins(drcbe_state *drcbe, x86code *dst, const drcuml_instruc
} }
else else
{ {
emit_mov_m32_r32(&dst, MBD(REG_ESP, -8), REG_EBX); // mov [esp-8],ebx int tempreg = REG_EBX;
emit_mov_r64_p64(drcbe, &dst, REG_EBX, REG_ECX, &maskp); // mov ecx:ebx,maskp emit_mov_m32_r32(&dst, MBD(REG_ESP, -8), tempreg); // mov [esp-8],ebx
emit_and_r32_r32(&dst, REG_EAX, REG_EBX); // and eax,ebx emit_mov_r64_p64(drcbe, &dst, tempreg, REG_ECX, &maskp); // mov ecx:ebx,maskp
emit_and_r32_r32(&dst, REG_EAX, tempreg); // and eax,ebx
emit_and_r32_r32(&dst, REG_EDX, REG_ECX); // and edx,ecx emit_and_r32_r32(&dst, REG_EDX, REG_ECX); // and edx,ecx
emit_not_r32(&dst, REG_EBX); // not ebx emit_not_r32(&dst, tempreg); // not ebx
emit_not_r32(&dst, REG_ECX); // not ecx emit_not_r32(&dst, REG_ECX); // not ecx
if (dstp.type == DRCUML_PTYPE_INT_REGISTER) if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
{ {
emit_and_r32_r32(&dst, dstp.value, REG_EBX); // and dstp.lo,ebx emit_and_r32_r32(&dst, dstp.value, tempreg); // and dstp.lo,ebx
emit_and_m32_r32(&dst, MABS(drcbe->reghi[dstp.value]), REG_ECX); // and dstp.hi,ecx emit_and_m32_r32(&dst, MABS(drcbe->reghi[dstp.value]), REG_ECX); // and dstp.hi,ecx
emit_or_r32_r32(&dst, dstp.value, REG_EAX); // or dstp.lo,eax emit_or_r32_r32(&dst, dstp.value, REG_EAX); // or dstp.lo,eax
emit_or_m32_r32(&dst, MABS(drcbe->reghi[dstp.value]), REG_EDX); // or dstp.hi,edx emit_or_m32_r32(&dst, MABS(drcbe->reghi[dstp.value]), REG_EDX); // or dstp.hi,edx
} }
else else
{ {
emit_and_m32_r32(&dst, MABS(dstp.value), REG_EBX); // and dstp.lo,ebx emit_and_m32_r32(&dst, MABS(dstp.value), tempreg); // and dstp.lo,ebx
emit_and_m32_r32(&dst, MABS(dstp.value + 4), REG_ECX); // and dstp.hi,ecx emit_and_m32_r32(&dst, MABS(dstp.value + 4), REG_ECX); // and dstp.hi,ecx
emit_or_m32_r32(&dst, MABS(dstp.value), REG_EAX); // or dstp.lo,eax emit_or_m32_r32(&dst, MABS(dstp.value), REG_EAX); // or dstp.lo,eax
emit_or_m32_r32(&dst, MABS(dstp.value + 4), REG_EDX); // or dstp.hi,edx emit_or_m32_r32(&dst, MABS(dstp.value + 4), REG_EDX); // or dstp.hi,edx
} }
emit_mov_r32_m32(&dst, REG_EBX, MBD(REG_ESP, -8)); // mov ebx,[esp-8] emit_mov_r32_m32(&dst, tempreg, MBD(REG_ESP, -8)); // mov ebx,[esp-8]
} }
if (inst->flags == DRCUML_FLAG_Z) if (inst->flags == DRCUML_FLAG_Z)
emit_or_r32_r32(&dst, REG_EAX, REG_EDX); // or eax,edx emit_or_r32_r32(&dst, REG_EAX, REG_EDX); // or eax,edx

View File

@ -549,12 +549,12 @@ void rspdrc_add_dmem(const device_config *device, void *base)
debugging debugging
-------------------------------------------------*/ -------------------------------------------------*/
static void cfunc_printf_debug(void *param) //static void cfunc_printf_debug(void *param)
{ //{
rsp_state *rsp = (rsp_state *)param; // rsp_state *rsp = (rsp_state *)param;
printf(rsp->impstate->format, rsp->impstate->arg0, rsp->impstate->arg1); // printf(rsp->impstate->format, rsp->impstate->arg0, rsp->impstate->arg1);
logerror(rsp->impstate->format, rsp->impstate->arg0, rsp->impstate->arg1); // logerror(rsp->impstate->format, rsp->impstate->arg0, rsp->impstate->arg1);
} //}
/*------------------------------------------------- /*-------------------------------------------------
@ -7312,10 +7312,10 @@ static void cfunc_unimplemented(void *param)
cfunc_fatalerror - a generic fatalerror call cfunc_fatalerror - a generic fatalerror call
-------------------------------------------------*/ -------------------------------------------------*/
static void cfunc_fatalerror(void *param) //static void cfunc_fatalerror(void *param)
{ //{
//fatalerror("fatalerror"); //fatalerror("fatalerror");
} //}
/*************************************************************************** /***************************************************************************
@ -7431,11 +7431,7 @@ static void static_generate_memory_accessor(rsp_state *rsp, int size, int iswrit
drcuml_state *drcuml = rsp->impstate->drcuml; drcuml_state *drcuml = rsp->impstate->drcuml;
drcuml_block *block; drcuml_block *block;
jmp_buf errorbuf; jmp_buf errorbuf;
int unaligned_w2 = 1; int unaligned_case = 1;
int aligned_w2 = 2;
int unaligned_w4 = 1;
int unaligned_r2 = 1;
int unaligned_r4 = 1;
/* if we get an error back, we're screwed */ /* if we get an error back, we're screwed */
if (setjmp(errorbuf) != 0) if (setjmp(errorbuf) != 0)
@ -7450,132 +7446,116 @@ static void static_generate_memory_accessor(rsp_state *rsp, int size, int iswrit
alloc_handle(drcuml, handleptr, name); alloc_handle(drcuml, handleptr, name);
UML_HANDLE(block, *handleptr); // handle *handleptr UML_HANDLE(block, *handleptr); // handle *handleptr
UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff));
// write: // write:
if (iswrite) if (iswrite)
{ {
if (size == 1) if (size == 1)
{ {
UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); // xor i0,i0,bytexor #ifdef LSB_FIRST
UML_STORE(block, rsp->impstate->dmem, IREG(0), IREG(1), BYTE); // store dmem,i0,i1,byte UML_XOR(block, IREG(0), IREG(0), IMM(3)); // xor i0,i0,3
#endif
UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff)); // and i0,i0,0xfff
UML_STORE(block, rsp->impstate->dmem, IREG(0), IREG(1), BYTE); // store dmem,i0,i1,byte
} }
else if (size == 2) else if (size == 2)
{ {
static const char text[] = "%08x: Unaligned word write to %08x\n"; #ifdef LSB_FIRST
UML_TEST(block, IREG(0), IMM(1)); // test i0,1 UML_TEST(block, IREG(0), IMM(1)); // test i0,1
UML_JMPc(block, IF_NZ, unaligned_w2); // jnz <unaligned_w2> UML_JMPc(block, IF_NZ, unaligned_case); // jnz <unaligned_case>
UML_JMP(block, aligned_w2); // jmp <aligned_w2> UML_XOR(block, IREG(0), IREG(0), IMM(2)); // xor i0,i0,2
#endif
UML_LABEL(block, unaligned_w2); // <unaligned_w2>: UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff)); // and i0,i0,0xfff
UML_MOV(block, MEM(&rsp->impstate->format), IMM((FPTR)text)); // mov [format],text UML_STORE(block, rsp->impstate->dmem, IREG(0), IREG(1), WORD_x1); // store dmem,i0,i1,word_x1
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(rsp->pc)); // mov [arg0],rsp->pc UML_RET(block);
UML_MOV(block, MEM(&rsp->impstate->arg1), IREG(0)); // mov [arg1],i0 #ifdef LSB_FIRST
UML_CALLC(block, cfunc_printf_debug, rsp); // callc printf_debug UML_LABEL(block, unaligned_case); // unaligned_case:
UML_CALLC(block, cfunc_fatalerror, rsp); UML_AND(block, IREG(2), IREG(0), IMM(3)); // and i2,i0,3
UML_AND(block, IREG(0), IREG(0), IMM(0xffc)); // and i0,i0,0xffc
UML_LABEL(block, aligned_w2); // <aligned_w2>: UML_SHL(block, IREG(2), IREG(2), IMM(3)); // shl i2,i2,3
UML_SHR(block, IREG(0), IREG(0), IMM(1)); // shr i0,i0,1 UML_DLOAD(block, IREG(3), rsp->impstate->dmem, IREG(0), QWORD_x1); // dload i3,dmem,i0,qword_x1
UML_XOR(block, IREG(0), IREG(0), IMM(BYTE_XOR_BE(0))); // xor i0,i0,bytexor UML_ADD(block, IREG(2), IREG(2), IMM(48)); // add i2,i2,48
UML_STORE(block, rsp->impstate->dmem, IREG(0), IREG(1), WORD); // store dmem,i0,i1,word UML_DROL(block, IREG(3), IREG(3), IREG(2)); // drol i3,i3,i2
UML_DAND(block, IREG(1), IREG(1), IMM(0xffff)); // dand i1,i1,0xffff
UML_DAND(block, IREG(3), IREG(3), IMM(U64(0xffffffffffff0000))); // dand i3,i3,~0xffff
UML_DOR(block, IREG(1), IREG(1), IREG(3)); // dor i1,i1,i3
UML_DROR(block, IREG(1), IREG(1), IREG(2)); // dror i1,i1,i2
UML_DSTORE(block, rsp->impstate->dmem, IREG(0), IREG(1), QWORD_x1); // dstore dmem,i0,i1,qword_x1
#endif
} }
else if (size == 4) else if (size == 4)
{ {
#ifdef LSB_FIRST
UML_TEST(block, IREG(0), IMM(3)); // test i0,3 UML_TEST(block, IREG(0), IMM(3)); // test i0,3
UML_JMPc(block, IF_NZ, unaligned_w4); // jnz <unaligned_w4> UML_JMPc(block, IF_NZ, unaligned_case); // jnz <unaligned_case>
#endif
UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff)); // and i0,i0,0xfff
UML_STORE(block, rsp->impstate->dmem, IREG(0), IREG(1), DWORD_x1); // store dmem,i0,i1,dword_x1 UML_STORE(block, rsp->impstate->dmem, IREG(0), IREG(1), DWORD_x1); // store dmem,i0,i1,dword_x1
UML_RET(block); UML_RET(block);
#ifdef LSB_FIRST
UML_LABEL(block, unaligned_w4); UML_LABEL(block, unaligned_case); // unaligned_case:
UML_ADD(block, IREG(0), IREG(0), IMM(3)); UML_AND(block, IREG(2), IREG(0), IMM(3)); // and i2,i0,3
UML_AND(block, IREG(0), IREG(0), IMM(0xffc)); // and i0,i0,0xffc
UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); UML_SHL(block, IREG(2), IREG(2), IMM(3)); // shl i2,i2,3
UML_STORE(block, rsp->impstate->dmem, IREG(0), IREG(1), BYTE); UML_DLOAD(block, IREG(3), rsp->impstate->dmem, IREG(0), QWORD_x1); // dload i3,dmem,i0,qword_x1
UML_ADD(block, IREG(2), IREG(2), IMM(48)); // add i2,i2,48
UML_SHR(block, IREG(1), IREG(1), IMM(8)); UML_DROL(block, IREG(3), IREG(3), IREG(2)); // drol i3,i3,i2
UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); UML_DAND(block, IREG(1), IREG(1), IMM(0xffffffff)); // dand i1,i1,0xffffffff
UML_SUB(block, IREG(0), IREG(0), IMM(1)); UML_DAND(block, IREG(3), IREG(3), IMM(U64(0xffffffff00000000))); // dand i3,i3,~0xffffffff
UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); UML_DOR(block, IREG(1), IREG(1), IREG(3)); // dor i1,i1,i3
UML_STORE(block, rsp->impstate->dmem, IREG(0), IREG(1), BYTE); UML_DROR(block, IREG(1), IREG(1), IREG(2)); // dror i1,i1,i2
UML_DSTORE(block, rsp->impstate->dmem, IREG(0), IREG(1), QWORD_x1); // dstore dmem,i0,i1,qword_x1
UML_SHR(block, IREG(1), IREG(1), IMM(8)); #endif
UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));
UML_SUB(block, IREG(0), IREG(0), IMM(1));
UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));
UML_STORE(block, rsp->impstate->dmem, IREG(0), IREG(1), BYTE);
UML_SHR(block, IREG(1), IREG(1), IMM(8));
UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));
UML_SUB(block, IREG(0), IREG(0), IMM(1));
UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));
UML_STORE(block, rsp->impstate->dmem, IREG(0), IREG(1), BYTE);
} }
} }
else else
{ {
if (size == 1) if (size == 1)
{ {
UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); // xor i0,i0,bytexor #ifdef LSB_FIRST
UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE); // load i0,dmem,i0,byte UML_XOR(block, IREG(0), IREG(0), IMM(3)); // xor i0,i0,3
#endif
UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff)); // and i0,i0,0xfff
UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE); // load i0,dmem,i0,byte
} }
else if (size == 2) else if (size == 2)
{ {
UML_TEST(block, IREG(0), IMM(1)); // test i0,3 #ifdef LSB_FIRST
UML_JMPc(block, IF_NZ, unaligned_r2); // jnz <unaligned_r2> UML_TEST(block, IREG(0), IMM(1)); // test i0,1
UML_JMPc(block, IF_NZ, unaligned_case); // jnz <unaligned_case>
UML_SHR(block, IREG(0), IREG(0), IMM(1)); // shr i0,i0,1 UML_XOR(block, IREG(0), IREG(0), IMM(2)); // xor i0,i0,2
UML_XOR(block, IREG(0), IREG(0), IMM(BYTE_XOR_BE(0))); // xor i0,i0,bytexor #endif
UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), WORD); // load i0,dmem,i0,word UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff)); // and i0,i0,0xfff
UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), WORD_x1); // load i0,dmem,i0,word_x1
UML_RET(block); UML_RET(block);
#ifdef LSB_FIRST
UML_LABEL(block, unaligned_r2); UML_LABEL(block, unaligned_case); // unaligned_case:
UML_MOV(block, IREG(2), IMM(0)); UML_AND(block, IREG(1), IREG(0), IMM(3)); // and i1,i0,3
UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); UML_AND(block, IREG(0), IREG(0), IMM(0xffc)); // and i0,i0,0xffc
UML_SHL(block, IREG(1), IREG(1), IMM(3)); // shl i1,i1,3
UML_LOAD(block, IREG(3), rsp->impstate->dmem, IREG(0), BYTE); UML_DLOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), QWORD_x1); // dload i0,dmem,i0,qword_x1
UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); UML_ADD(block, IREG(1), IREG(1), IMM(48)); // add i1,i1,48
UML_ADD(block, IREG(0), IREG(0), IMM(1)); UML_DROL(block, IREG(0), IREG(0), IREG(1)); // drol i0,i0,i1
UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); UML_AND(block, IREG(0), IREG(0), IMM(0xffff)); // and i0,i0,0xffff
UML_OR(block, IREG(2), IREG(2), IREG(3)); #endif
UML_LOAD(block, IREG(3), rsp->impstate->dmem, IREG(0), BYTE);
UML_ADD(block, IREG(0), IREG(0), IMM(1));
UML_SHL(block, IREG(2), IREG(2), IMM(8));
UML_OR(block, IREG(2), IREG(2), IREG(3));
UML_MOV(block, IREG(0), IREG(2));
} }
else if (size == 4) else if (size == 4)
{ {
UML_TEST(block, IREG(0), IMM(3)); // test i0,3 #ifdef LSB_FIRST
UML_JMPc(block, IF_NZ, unaligned_r4); // jnz <unaligned_r4> UML_TEST(block, IREG(0), IMM(3)); // test i0,3
UML_JMPc(block, IF_NZ, unaligned_case); // jnz <unaligned_case>
UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), DWORD_x1); // load i0,dmem,i0,dword #endif
UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff)); // and i0,i0,0xfff
UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), DWORD_x1); // load i0,dmem,i0,dword_x1
UML_RET(block); UML_RET(block);
#ifdef LSB_FIRST
UML_LABEL(block, unaligned_r4); UML_LABEL(block, unaligned_case); // unaligned_case:
UML_AND(block, IREG(1), IREG(0), IMM(3)); // and i1,i0,3
UML_XOR(block, IREG(1), IREG(0), IMM(BYTE4_XOR_BE(0))); UML_AND(block, IREG(0), IREG(0), IMM(0xffc)); // and i0,i0,0xffc
UML_LOAD(block, IREG(3), rsp->impstate->dmem, IREG(1), BYTE); UML_SHL(block, IREG(1), IREG(1), IMM(3)); // shl i1,i1,3
UML_SHL(block, IREG(2), IREG(3), IMM(24)); UML_DLOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), QWORD_x1); // dload i0,dmem,i0,qword_x1
UML_ADD(block, IREG(1), IREG(1), IMM(48)); // add i1,i1,48
UML_ADD(block, IREG(1), IREG(0), IMM(1)); UML_DROL(block, IREG(0), IREG(0), IREG(1)); // drol i0,i0,i1
UML_XOR(block, IREG(1), IREG(1), IMM(BYTE4_XOR_BE(0))); #endif
UML_LOAD(block, IREG(3), rsp->impstate->dmem, IREG(1), BYTE);
UML_SHL(block, IREG(3), IREG(3), IMM(16));
UML_OR(block, IREG(2), IREG(2), IREG(3));
UML_ADD(block, IREG(1), IREG(0), IMM(2));
UML_XOR(block, IREG(1), IREG(1), IMM(BYTE4_XOR_BE(0)));
UML_LOAD(block, IREG(3), rsp->impstate->dmem, IREG(1), BYTE);
UML_SHL(block, IREG(3), IREG(3), IMM(8));
UML_OR(block, IREG(2), IREG(2), IREG(3));
UML_ADD(block, IREG(1), IREG(0), IMM(3));
UML_XOR(block, IREG(1), IREG(1), IMM(BYTE4_XOR_BE(0)));
UML_LOAD(block, IREG(3), rsp->impstate->dmem, IREG(1), BYTE);
UML_OR(block, IREG(0), IREG(2), IREG(3));
} }
} }
UML_RET(block); UML_RET(block);