Commit d796321b6b552284080af5560030e9c8d0f06321
1 parent
567d4107
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
Showing
2 changed files
with
21 additions
and
2 deletions
target-mips/op_mem.c
@@ -61,6 +61,12 @@ void glue(op_lw, MEMSUFFIX) (void) | @@ -61,6 +61,12 @@ void glue(op_lw, MEMSUFFIX) (void) | ||
61 | RETURN(); | 61 | RETURN(); |
62 | } | 62 | } |
63 | 63 | ||
64 | +void glue(op_lwu, MEMSUFFIX) (void) | ||
65 | +{ | ||
66 | + T0 = glue(ldl, MEMSUFFIX)(T0); | ||
67 | + RETURN(); | ||
68 | +} | ||
69 | + | ||
64 | void glue(op_sw, MEMSUFFIX) (void) | 70 | void glue(op_sw, MEMSUFFIX) (void) |
65 | { | 71 | { |
66 | glue(stl, MEMSUFFIX)(T0, T1); | 72 | glue(stl, MEMSUFFIX)(T0, T1); |
target-mips/translate.c
@@ -97,6 +97,7 @@ enum { | @@ -97,6 +97,7 @@ enum { | ||
97 | OPC_LBU = 0x24, | 97 | OPC_LBU = 0x24, |
98 | OPC_LHU = 0x25, | 98 | OPC_LHU = 0x25, |
99 | OPC_LWR = 0x26, | 99 | OPC_LWR = 0x26, |
100 | + OPC_LWU = 0x27, | ||
100 | OPC_SB = 0x28, | 101 | OPC_SB = 0x28, |
101 | OPC_SH = 0x29, | 102 | OPC_SH = 0x29, |
102 | OPC_SWL = 0x2A, | 103 | OPC_SWL = 0x2A, |
@@ -495,6 +496,7 @@ OP_ST_TABLE(dl); | @@ -495,6 +496,7 @@ OP_ST_TABLE(dl); | ||
495 | OP_ST_TABLE(dr); | 496 | OP_ST_TABLE(dr); |
496 | #endif | 497 | #endif |
497 | OP_LD_TABLE(w); | 498 | OP_LD_TABLE(w); |
499 | +OP_LD_TABLE(wu); | ||
498 | OP_LD_TABLE(wl); | 500 | OP_LD_TABLE(wl); |
499 | OP_LD_TABLE(wr); | 501 | OP_LD_TABLE(wr); |
500 | OP_ST_TABLE(w); | 502 | OP_ST_TABLE(w); |
@@ -580,6 +582,11 @@ static void gen_ldst (DisasContext *ctx, uint16_t opc, int rt, | @@ -580,6 +582,11 @@ static void gen_ldst (DisasContext *ctx, uint16_t opc, int rt, | ||
580 | GEN_STORE_TN_REG(rt, T0); | 582 | GEN_STORE_TN_REG(rt, T0); |
581 | opn = "lw"; | 583 | opn = "lw"; |
582 | break; | 584 | break; |
585 | + case OPC_LWU: | ||
586 | + op_ldst(lwu); | ||
587 | + GEN_STORE_TN_REG(rt, T0); | ||
588 | + opn = "lwu"; | ||
589 | + break; | ||
583 | case OPC_SW: | 590 | case OPC_SW: |
584 | #if defined (MIPS_HAS_UNALIGNED_LS) | 591 | #if defined (MIPS_HAS_UNALIGNED_LS) |
585 | case OPC_USW: | 592 | case OPC_USW: |
@@ -1356,6 +1363,7 @@ static void gen_cp0 (DisasContext *ctx, uint16_t opc, int rt, int rd) | @@ -1356,6 +1363,7 @@ static void gen_cp0 (DisasContext *ctx, uint16_t opc, int rt, int rd) | ||
1356 | generate_exception_err (ctx, EXCP_CpU, 0); | 1363 | generate_exception_err (ctx, EXCP_CpU, 0); |
1357 | return; | 1364 | return; |
1358 | } | 1365 | } |
1366 | + | ||
1359 | switch (opc) { | 1367 | switch (opc) { |
1360 | case OPC_MFC0: | 1368 | case OPC_MFC0: |
1361 | if (rt == 0) { | 1369 | if (rt == 0) { |
@@ -1886,6 +1894,12 @@ static void decode_opc (DisasContext *ctx) | @@ -1886,6 +1894,12 @@ static void decode_opc (DisasContext *ctx) | ||
1886 | uint16_t op, op1; | 1894 | uint16_t op, op1; |
1887 | int16_t imm; | 1895 | int16_t imm; |
1888 | 1896 | ||
1897 | + /* make sure instructions are on a word boundary */ | ||
1898 | + if (ctx->pc & 0x3) { | ||
1899 | + generate_exception(ctx, EXCP_AdEL); | ||
1900 | + return; | ||
1901 | + } | ||
1902 | + | ||
1889 | if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) { | 1903 | if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) { |
1890 | /* Handle blikely not taken case */ | 1904 | /* Handle blikely not taken case */ |
1891 | MIPS_DEBUG("blikely condition (%08x)", ctx->pc + 4); | 1905 | MIPS_DEBUG("blikely condition (%08x)", ctx->pc + 4); |
@@ -2041,8 +2055,7 @@ static void decode_opc (DisasContext *ctx) | @@ -2041,8 +2055,7 @@ static void decode_opc (DisasContext *ctx) | ||
2041 | case 0x14 ... 0x17: | 2055 | case 0x14 ... 0x17: |
2042 | gen_compute_branch(ctx, op, rs, rt, imm << 2); | 2056 | gen_compute_branch(ctx, op, rs, rt, imm << 2); |
2043 | return; | 2057 | return; |
2044 | - case 0x20 ... 0x26: /* Load and stores */ | ||
2045 | - case 0x28 ... 0x2E: | 2058 | + case 0x20 ... 0x2E: /* Load and stores */ |
2046 | case 0x30: | 2059 | case 0x30: |
2047 | case 0x38: | 2060 | case 0x38: |
2048 | gen_ldst(ctx, op, rt, rs, imm); | 2061 | gen_ldst(ctx, op, rt, rs, imm); |