mirror of https://github.com/xqemu/xqemu.git
Fix rotr immediate ops, mask shift/rotate arguments to their allowed
size. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2614 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
acd858d91f
commit
5a63bcb2d2
|
@ -493,19 +493,19 @@ void op_xor (void)
|
||||||
|
|
||||||
void op_sll (void)
|
void op_sll (void)
|
||||||
{
|
{
|
||||||
T0 = (int32_t)((uint32_t)T0 << (uint32_t)T1);
|
T0 = (int32_t)((uint32_t)T0 << T1);
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_sra (void)
|
void op_sra (void)
|
||||||
{
|
{
|
||||||
T0 = (int32_t)((int32_t)T0 >> (uint32_t)T1);
|
T0 = (int32_t)((int32_t)T0 >> T1);
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_srl (void)
|
void op_srl (void)
|
||||||
{
|
{
|
||||||
T0 = (int32_t)((uint32_t)T0 >> (uint32_t)T1);
|
T0 = (int32_t)((uint32_t)T0 >> T1);
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,10 +514,9 @@ void op_rotr (void)
|
||||||
target_ulong tmp;
|
target_ulong tmp;
|
||||||
|
|
||||||
if (T1) {
|
if (T1) {
|
||||||
tmp = (int32_t)((uint32_t)T0 << (0x20 - (uint32_t)T1));
|
tmp = (int32_t)((uint32_t)T0 << (0x20 - T1));
|
||||||
T0 = (int32_t)((uint32_t)T0 >> (uint32_t)T1) | tmp;
|
T0 = (int32_t)((uint32_t)T0 >> T1) | tmp;
|
||||||
} else
|
}
|
||||||
T0 = T1;
|
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -707,8 +706,7 @@ void op_drotr (void)
|
||||||
if (T1) {
|
if (T1) {
|
||||||
tmp = T0 << (0x40 - T1);
|
tmp = T0 << (0x40 - T1);
|
||||||
T0 = (T0 >> T1) | tmp;
|
T0 = (T0 >> T1) | tmp;
|
||||||
} else
|
}
|
||||||
T0 = T1;
|
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -719,8 +717,7 @@ void op_drotr32 (void)
|
||||||
if (T1) {
|
if (T1) {
|
||||||
tmp = T0 << (0x40 - (32 + T1));
|
tmp = T0 << (0x40 - (32 + T1));
|
||||||
T0 = (T0 >> (32 + T1)) | tmp;
|
T0 = (T0 >> (32 + T1)) | tmp;
|
||||||
} else
|
}
|
||||||
T0 = T1;
|
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,8 +120,7 @@ void do_drotr (void)
|
||||||
if (T1) {
|
if (T1) {
|
||||||
tmp = T0 << (0x40 - T1);
|
tmp = T0 << (0x40 - T1);
|
||||||
T0 = (T0 >> T1) | tmp;
|
T0 = (T0 >> T1) | tmp;
|
||||||
} else
|
}
|
||||||
T0 = T1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_drotr32 (void)
|
void do_drotr32 (void)
|
||||||
|
@ -131,8 +130,7 @@ void do_drotr32 (void)
|
||||||
if (T1) {
|
if (T1) {
|
||||||
tmp = T0 << (0x40 - (32 + T1));
|
tmp = T0 << (0x40 - (32 + T1));
|
||||||
T0 = (T0 >> (32 + T1)) | tmp;
|
T0 = (T0 >> (32 + T1)) | tmp;
|
||||||
} else
|
}
|
||||||
T0 = T1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_dsllv (void)
|
void do_dsllv (void)
|
||||||
|
|
|
@ -849,18 +849,43 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
|
||||||
MIPS_DEBUG("NOP");
|
MIPS_DEBUG("NOP");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (opc == OPC_ADDI || opc == OPC_ADDIU ||
|
uimm = (uint16_t)imm;
|
||||||
opc == OPC_DADDI || opc == OPC_DADDIU ||
|
switch (opc) {
|
||||||
opc == OPC_SLTI || opc == OPC_SLTIU)
|
case OPC_ADDI:
|
||||||
|
case OPC_ADDIU:
|
||||||
|
#ifdef TARGET_MIPS64
|
||||||
|
case OPC_DADDI:
|
||||||
|
case OPC_DADDIU:
|
||||||
|
#endif
|
||||||
|
case OPC_SLTI:
|
||||||
|
case OPC_SLTIU:
|
||||||
uimm = (int32_t)imm; /* Sign extend to 32 bits */
|
uimm = (int32_t)imm; /* Sign extend to 32 bits */
|
||||||
else
|
/* Fall through. */
|
||||||
uimm = (uint16_t)imm;
|
case OPC_ANDI:
|
||||||
if (opc != OPC_LUI) {
|
case OPC_ORI:
|
||||||
|
case OPC_XORI:
|
||||||
GEN_LOAD_REG_TN(T0, rs);
|
GEN_LOAD_REG_TN(T0, rs);
|
||||||
GEN_LOAD_IMM_TN(T1, uimm);
|
GEN_LOAD_IMM_TN(T1, uimm);
|
||||||
} else {
|
break;
|
||||||
uimm = uimm << 16;
|
case OPC_LUI:
|
||||||
|
uimm <<= 16;
|
||||||
GEN_LOAD_IMM_TN(T0, uimm);
|
GEN_LOAD_IMM_TN(T0, uimm);
|
||||||
|
break;
|
||||||
|
case OPC_SLL:
|
||||||
|
case OPC_SRA:
|
||||||
|
case OPC_SRL:
|
||||||
|
#ifdef TARGET_MIPS64
|
||||||
|
case OPC_DSLL:
|
||||||
|
case OPC_DSRA:
|
||||||
|
case OPC_DSRL:
|
||||||
|
case OPC_DSLL32:
|
||||||
|
case OPC_DSRA32:
|
||||||
|
case OPC_DSRL32:
|
||||||
|
#endif
|
||||||
|
uimm &= 0x1f;
|
||||||
|
GEN_LOAD_REG_TN(T0, rs);
|
||||||
|
GEN_LOAD_IMM_TN(T1, uimm);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
switch (opc) {
|
switch (opc) {
|
||||||
case OPC_ADDI:
|
case OPC_ADDI:
|
||||||
|
@ -915,13 +940,20 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
|
||||||
opn = "sra";
|
opn = "sra";
|
||||||
break;
|
break;
|
||||||
case OPC_SRL:
|
case OPC_SRL:
|
||||||
if ((ctx->opcode >> 21) & 1) {
|
switch ((ctx->opcode >> 21) & 0x1f) {
|
||||||
gen_op_rotr();
|
case 0:
|
||||||
opn = "rotr";
|
|
||||||
} else {
|
|
||||||
gen_op_srl();
|
gen_op_srl();
|
||||||
opn = "srl";
|
opn = "srl";
|
||||||
}
|
break;
|
||||||
|
case 1:
|
||||||
|
gen_op_rotr();
|
||||||
|
opn = "rotr";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
MIPS_INVAL("invalid srl flag");
|
||||||
|
generate_exception(ctx, EXCP_RI);
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
#ifdef TARGET_MIPS64
|
#ifdef TARGET_MIPS64
|
||||||
case OPC_DSLL:
|
case OPC_DSLL:
|
||||||
|
@ -933,13 +965,20 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
|
||||||
opn = "dsra";
|
opn = "dsra";
|
||||||
break;
|
break;
|
||||||
case OPC_DSRL:
|
case OPC_DSRL:
|
||||||
if ((ctx->opcode >> 21) & 1) {
|
switch ((ctx->opcode >> 21) & 0x1f) {
|
||||||
gen_op_drotr();
|
case 0:
|
||||||
opn = "drotr";
|
|
||||||
} else {
|
|
||||||
gen_op_dsrl();
|
gen_op_dsrl();
|
||||||
opn = "dsrl";
|
opn = "dsrl";
|
||||||
}
|
break;
|
||||||
|
case 1:
|
||||||
|
gen_op_drotr();
|
||||||
|
opn = "drotr";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
MIPS_INVAL("invalid dsrl flag");
|
||||||
|
generate_exception(ctx, EXCP_RI);
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OPC_DSLL32:
|
case OPC_DSLL32:
|
||||||
gen_op_dsll32();
|
gen_op_dsll32();
|
||||||
|
@ -950,13 +989,20 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
|
||||||
opn = "dsra32";
|
opn = "dsra32";
|
||||||
break;
|
break;
|
||||||
case OPC_DSRL32:
|
case OPC_DSRL32:
|
||||||
if ((ctx->opcode >> 21) & 1) {
|
switch ((ctx->opcode >> 21) & 0x1f) {
|
||||||
gen_op_drotr32();
|
case 0:
|
||||||
opn = "drotr32";
|
|
||||||
} else {
|
|
||||||
gen_op_dsrl32();
|
gen_op_dsrl32();
|
||||||
opn = "dsrl32";
|
opn = "dsrl32";
|
||||||
}
|
break;
|
||||||
|
case 1:
|
||||||
|
gen_op_drotr32();
|
||||||
|
opn = "drotr32";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
MIPS_INVAL("invalid dsrl32 flag");
|
||||||
|
generate_exception(ctx, EXCP_RI);
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
|
@ -1068,13 +1114,20 @@ static void gen_arith (DisasContext *ctx, uint32_t opc,
|
||||||
opn = "srav";
|
opn = "srav";
|
||||||
break;
|
break;
|
||||||
case OPC_SRLV:
|
case OPC_SRLV:
|
||||||
if ((ctx->opcode >> 6) & 1) {
|
switch ((ctx->opcode >> 6) & 0x1f) {
|
||||||
gen_op_rotrv();
|
case 0:
|
||||||
opn = "rotrv";
|
|
||||||
} else {
|
|
||||||
gen_op_srlv();
|
gen_op_srlv();
|
||||||
opn = "srlv";
|
opn = "srlv";
|
||||||
}
|
break;
|
||||||
|
case 1:
|
||||||
|
gen_op_rotrv();
|
||||||
|
opn = "rotrv";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
MIPS_INVAL("invalid srlv flag");
|
||||||
|
generate_exception(ctx, EXCP_RI);
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
#ifdef TARGET_MIPS64
|
#ifdef TARGET_MIPS64
|
||||||
case OPC_DSLLV:
|
case OPC_DSLLV:
|
||||||
|
@ -1086,13 +1139,20 @@ static void gen_arith (DisasContext *ctx, uint32_t opc,
|
||||||
opn = "dsrav";
|
opn = "dsrav";
|
||||||
break;
|
break;
|
||||||
case OPC_DSRLV:
|
case OPC_DSRLV:
|
||||||
if ((ctx->opcode >> 6) & 1) {
|
switch ((ctx->opcode >> 6) & 0x1f) {
|
||||||
gen_op_drotrv();
|
case 0:
|
||||||
opn = "drotrv";
|
|
||||||
} else {
|
|
||||||
gen_op_dsrlv();
|
gen_op_dsrlv();
|
||||||
opn = "dsrlv";
|
opn = "dsrlv";
|
||||||
}
|
break;
|
||||||
|
case 1:
|
||||||
|
gen_op_drotrv();
|
||||||
|
opn = "drotrv";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
MIPS_INVAL("invalid dsrlv flag");
|
||||||
|
generate_exception(ctx, EXCP_RI);
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in New Issue