diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2006-06-26 20:02:45 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2006-06-26 20:02:45 +0000 |
commit | d796321b6b552284080af5560030e9c8d0f06321 (patch) | |
tree | 6e9102e3c47134eff6765c87de7f26f9ca51a5c5 /target-mips | |
parent | 567d4107a67571f57bb5f8879258414a87f98a2b (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.c | 6 | ||||
-rw-r--r-- | target-mips/translate.c | 17 |
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); |