aboutsummaryrefslogtreecommitdiff
path: root/target-mips
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2006-06-26 20:02:45 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2006-06-26 20:02:45 +0000
commitd796321b6b552284080af5560030e9c8d0f06321 (patch)
tree6e9102e3c47134eff6765c87de7f26f9ca51a5c5 /target-mips
parent567d4107a67571f57bb5f8879258414a87f98a2b (diff)
lwu support - generate exception if unaligned pc (Marius Groeger)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2025 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-mips')
-rw-r--r--target-mips/op_mem.c6
-rw-r--r--target-mips/translate.c17
2 files changed, 21 insertions, 2 deletions
diff --git a/target-mips/op_mem.c b/target-mips/op_mem.c
index b5308bea57..35ccd44c66 100644
--- a/target-mips/op_mem.c
+++ b/target-mips/op_mem.c
@@ -61,6 +61,12 @@ void glue(op_lw, MEMSUFFIX) (void)
RETURN();
}
+void glue(op_lwu, MEMSUFFIX) (void)
+{
+ T0 = glue(ldl, MEMSUFFIX)(T0);
+ RETURN();
+}
+
void glue(op_sw, MEMSUFFIX) (void)
{
glue(stl, MEMSUFFIX)(T0, T1);
diff --git a/target-mips/translate.c b/target-mips/translate.c
index fcee08747d..7ad8ebddf7 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -97,6 +97,7 @@ enum {
OPC_LBU = 0x24,
OPC_LHU = 0x25,
OPC_LWR = 0x26,
+ OPC_LWU = 0x27,
OPC_SB = 0x28,
OPC_SH = 0x29,
OPC_SWL = 0x2A,
@@ -495,6 +496,7 @@ OP_ST_TABLE(dl);
OP_ST_TABLE(dr);
#endif
OP_LD_TABLE(w);
+OP_LD_TABLE(wu);
OP_LD_TABLE(wl);
OP_LD_TABLE(wr);
OP_ST_TABLE(w);
@@ -580,6 +582,11 @@ static void gen_ldst (DisasContext *ctx, uint16_t opc, int rt,
GEN_STORE_TN_REG(rt, T0);
opn = "lw";
break;
+ case OPC_LWU:
+ op_ldst(lwu);
+ GEN_STORE_TN_REG(rt, T0);
+ opn = "lwu";
+ break;
case OPC_SW:
#if defined (MIPS_HAS_UNALIGNED_LS)
case OPC_USW:
@@ -1356,6 +1363,7 @@ static void gen_cp0 (DisasContext *ctx, uint16_t opc, int rt, int rd)
generate_exception_err (ctx, EXCP_CpU, 0);
return;
}
+
switch (opc) {
case OPC_MFC0:
if (rt == 0) {
@@ -1886,6 +1894,12 @@ static void decode_opc (DisasContext *ctx)
uint16_t op, op1;
int16_t imm;
+ /* make sure instructions are on a word boundary */
+ if (ctx->pc & 0x3) {
+ generate_exception(ctx, EXCP_AdEL);
+ return;
+ }
+
if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
/* Handle blikely not taken case */
MIPS_DEBUG("blikely condition (%08x)", ctx->pc + 4);
@@ -2041,8 +2055,7 @@ static void decode_opc (DisasContext *ctx)
case 0x14 ... 0x17:
gen_compute_branch(ctx, op, rs, rt, imm << 2);
return;
- case 0x20 ... 0x26: /* Load and stores */
- case 0x28 ... 0x2E:
+ case 0x20 ... 0x2E: /* Load and stores */
case 0x30:
case 0x38:
gen_ldst(ctx, op, rt, rs, imm);