diff --git a/decode1.vhdl b/decode1.vhdl index 3f3109f..b807054 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -93,7 +93,6 @@ architecture behaviour of decode1 is 43 => (LDST, NONE, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', ZERO, '0', is2B, '0', '1', '1', '0', '0', '0', NONE, '0', '0', DUPD), -- lhau 40 => (LDST, NONE, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', ZERO, '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', NONE), -- lhz 41 => (LDST, NONE, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', ZERO, '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '0', DUPD), -- lhzu - 56 => (LDST, NONE, OP_LOAD, RA_OR_ZERO, CONST_DQ, NONE, RT, '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', DRTE), -- lq 32 => (LDST, NONE, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', ZERO, '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', NONE), -- lwz 33 => (LDST, NONE, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', ZERO, '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '0', DUPD), -- lwzu 7 => (ALU, NONE, OP_MUL_L64, RA, CONST_SI, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '0', NONE), -- mulli @@ -310,7 +309,6 @@ architecture behaviour of decode1 is 2#1100110101# => (LDST, NONE, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', NONE), -- lhzcix 2#0100110111# => (LDST, NONE, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '0', DUPD), -- lhzux 2#0100010111# => (LDST, NONE, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', NONE), -- lhzx - 2#0100010100# => (LDST, NONE, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '1', '0', '0', NONE, '0', '0', DRTE), -- lqarx 2#0000010100# => (LDST, NONE, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', is4B, '0', '0', '0', '1', '0', '0', NONE, '0', '0', NONE), -- lwarx 2#0101110101# => (LDST, NONE, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', is4B, '0', '1', '1', '0', '0', '0', NONE, '0', '0', DUPD), -- lwaux 2#0101010101# => (LDST, NONE, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', is4B, '0', '1', '0', '0', '0', '0', NONE, '0', '0', NONE), -- lwax @@ -393,7 +391,6 @@ architecture behaviour of decode1 is 2#1011010110# => (LDST, NONE, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', ZERO, '0', is2B, '0', '0', '0', '1', '0', '0', ONE, '0', '0', NONE), -- sthcx 2#0110110111# => (LDST, NONE, OP_STORE, RA_OR_ZERO, RB, RS, RA, '0', '0', '0', '0', ZERO, '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '0', NONE), -- sthux 2#0110010111# => (LDST, NONE, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', ZERO, '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', NONE), -- sthx - 2#0010110110# => (LDST, NONE, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '1', '0', '0', ONE, '0', '0', DRSE), -- stqcx 2#1010010110# => (LDST, NONE, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', ZERO, '0', is4B, '1', '0', '0', '0', '0', '0', NONE, '0', '0', NONE), -- stwbrx 2#1110010101# => (LDST, NONE, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', ZERO, '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', NONE), -- stwcix 2#0010010110# => (LDST, NONE, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', ZERO, '0', is4B, '0', '0', '0', '1', '0', '0', ONE, '0', '0', NONE), -- stwcx @@ -452,7 +449,6 @@ architecture behaviour of decode1 is -- op in out A out in out len ext pipe 0 => (LDST, NONE, OP_STORE, RA_OR_ZERO, CONST_DS, RS, NONE, '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', NONE), -- std 1 => (LDST, NONE, OP_STORE, RA_OR_ZERO, CONST_DS, RS, RA, '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '0', NONE), -- stdu - 2 => (LDST, NONE, OP_STORE, RA_OR_ZERO, CONST_DS, RS, NONE, '0', '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', DRSE), -- stq others => decode_rom_init ); @@ -652,13 +648,6 @@ begin end case; end if; end if; - if std_match(f_in.insn(10 downto 1), "0100010100") then - -- lqarx, illegal if RA = RT or RB = RT - if f_in.insn(25 downto 21) = f_in.insn(20 downto 16) or - f_in.insn(25 downto 21) = f_in.insn(15 downto 11) then - vi.override := '1'; - end if; - end if; when 16 => -- CTR may be needed as input to bc @@ -722,12 +711,6 @@ begin when 30 => v.decode := decode_op_30_array(to_integer(unsigned(f_in.insn(4 downto 1)))); - when 56 => - -- lq, illegal if RA = RT - if f_in.insn(25 downto 21) = f_in.insn(20 downto 16) then - vi.override := '1'; - end if; - when 58 => v.decode := decode_op_58_array(to_integer(unsigned(f_in.insn(1 downto 0)))); diff --git a/decode2.vhdl b/decode2.vhdl index 1d4ce57..371c48c 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -406,16 +406,6 @@ begin v.e.repeat := '1'; v.e.second := dc2.repeat; case d_in.decode.repeat is - when DRSE => - -- do RS|1,RS for LE; RS,RS|1 for BE - if dc2.repeat = d_in.big_endian then - decoded_reg_c.reg(0) := '1'; - end if; - when DRTE => - -- do RT|1,RT for LE; RT,RT|1 for BE - if dc2.repeat = d_in.big_endian then - decoded_reg_o.reg(0) := '1'; - end if; when DUPD => -- update-form loads, 2nd instruction writes RA if dc2.repeat = '1' then diff --git a/decode_types.vhdl b/decode_types.vhdl index 885cc91..514bc08 100644 --- a/decode_types.vhdl +++ b/decode_types.vhdl @@ -53,8 +53,6 @@ package decode_types is type length_t is (NONE, is1B, is2B, is4B, is8B); type repeat_t is (NONE, -- instruction is not repeated - DRSE, -- double RS, endian twist - DRTE, -- double RT, endian twist DUPD); -- update-form load type decode_rom_t is record diff --git a/loadstore1.vhdl b/loadstore1.vhdl index ff2633b..7fad454 100644 --- a/loadstore1.vhdl +++ b/loadstore1.vhdl @@ -458,17 +458,6 @@ begin -- check alignment for larx/stcx misaligned := or (addr_mask and addr(2 downto 0)); v.align_intr := l_in.reserve and misaligned; - if l_in.repeat = '1' and l_in.second = '0' and l_in.update = '0' and addr(3) = '1' then - -- length is really 16 not 8 - -- Make misaligned lq cause an alignment interrupt in LE mode, - -- in order to avoid the case with RA = RT + 1 where the second half - -- faults but the first doesn't (and updates RT+1, destroying RA). - -- The equivalent BE case doesn't occur because RA = RT is illegal. - misaligned := '1'; - if l_in.reserve = '1' or (l_in.op = OP_LOAD and l_in.byte_reverse = '0') then - v.align_intr := '1'; - end if; - end if; v.atomic := not misaligned; v.atomic_last := not misaligned and (l_in.second or not l_in.repeat); diff --git a/tests/modes/head.S b/tests/modes/head.S index 8b00bdd..d9e69dc 100644 --- a/tests/modes/head.S +++ b/tests/modes/head.S @@ -230,63 +230,3 @@ restore: ld %r0,16(%r1) mtlr %r0 blr - - .global do_lq -do_lq: - lq %r6,0(%r3) - std %r6,0(%r4) - std %r7,8(%r4) - li %r3,0 - blr - - .global do_lq_np /* "non-preferred" form of lq */ -do_lq_np: - mr %r7,%r3 - lq %r6,0(%r7) - std %r6,0(%r4) - std %r7,8(%r4) - li %r3,0 - blr - - .global do_lq_bad /* illegal form of lq */ -do_lq_bad: - mr %r6,%r3 - .long 0xe0c60000 /* lq %r6,0(%r6) */ - std %r6,0(%r4) - std %r7,8(%r4) - li %r3,0 - blr - - .global do_stq -do_stq: - ld %r8,0(%r4) - ld %r9,8(%r4) - stq %r8,0(%r3) - li %r3,0 - blr - - /* big-endian versions of the above */ - .global do_lq_be -do_lq_be: - .long 0x0000c3e0 - .long 0x0000c4f8 - .long 0x0800e4f8 - .long 0x00006038 - .long 0x2000804e - - .global do_lq_np_be /* "non-preferred" form of lq */ -do_lq_np_be: - .long 0x781b677c - .long 0x0000c7e0 - .long 0x0000c4f8 - .long 0x0800e4f8 - .long 0x00006038 - .long 0x2000804e - - .global do_stq_be -do_stq_be: - .long 0x000004e9 - .long 0x080024e9 - .long 0x020003f9 - .long 0x00006038 - .long 0x2000804e diff --git a/tests/modes/modes.c b/tests/modes/modes.c index b94bb47..fa4872c 100644 --- a/tests/modes/modes.c +++ b/tests/modes/modes.c @@ -12,14 +12,6 @@ extern unsigned long callit(unsigned long arg1, unsigned long arg2, unsigned long fn, unsigned long msr); -extern void do_lq(void *src, unsigned long *regs); -extern void do_lq_np(void *src, unsigned long *regs); -extern void do_lq_bad(void *src, unsigned long *regs); -extern void do_stq(void *dst, unsigned long *regs); -extern void do_lq_be(void *src, unsigned long *regs); -extern void do_lq_np_be(void *src, unsigned long *regs); -extern void do_stq_be(void *dst, unsigned long *regs); - static inline void do_tlbie(unsigned long rb, unsigned long rs) { __asm__ volatile("tlbie %0,%1" : : "r" (rb), "r" (rs) : "memory"); @@ -302,167 +294,6 @@ int mode_test_6(void) return 0; } -int mode_test_7(void) -{ - unsigned long quad[4] __attribute__((__aligned__(16))); - unsigned long regs[2]; - unsigned long ret, msr; - - /* - * Test lq/stq in LE mode - */ - msr = MSR_SF | MSR_LE; - quad[0] = 0x123456789abcdef0ul; - quad[1] = 0xfafa5959bcbc3434ul; - ret = callit((unsigned long)quad, (unsigned long)regs, - (unsigned long)&do_lq, msr); - if (ret) - return ret | 1; - if (regs[0] != quad[1] || regs[1] != quad[0]) - return 2; - /* unaligned may give alignment interrupt */ - quad[2] = 0x0011223344556677ul; - ret = callit((unsigned long)&quad[1], (unsigned long)regs, - (unsigned long)&do_lq, msr); - if (ret == 0) { - if (regs[0] != quad[2] || regs[1] != quad[1]) - return 3; - } else if (ret == 0x600) { - if (mfspr(SPRG0) != (unsigned long) &do_lq || - mfspr(DAR) != (unsigned long) &quad[1]) - return ret | 4; - } else - return ret | 5; - - /* try stq */ - regs[0] = 0x5238523852385238ul; - regs[1] = 0x5239523952395239ul; - ret = callit((unsigned long)quad, (unsigned long)regs, - (unsigned long)&do_stq, msr); - if (ret) - return ret | 5; - if (quad[0] != regs[1] || quad[1] != regs[0]) - return 6; - regs[0] = 0x0172686966746564ul; - regs[1] = 0xfe8d0badd00dabcdul; - ret = callit((unsigned long)quad + 1, (unsigned long)regs, - (unsigned long)&do_stq, msr); - if (ret) - return ret | 7; - if (((quad[0] >> 8) | (quad[1] << 56)) != regs[1] || - ((quad[1] >> 8) | (quad[2] << 56)) != regs[0]) - return 8; - - /* try lq non-preferred form */ - quad[0] = 0x56789abcdef01234ul; - quad[1] = 0x5959bcbc3434fafaul; - ret = callit((unsigned long)quad, (unsigned long)regs, - (unsigned long)&do_lq_np, msr); - if (ret) - return ret | 9; - if (regs[0] != quad[1] || regs[1] != quad[0]) - return 10; - /* unaligned should give alignment interrupt in uW implementation */ - quad[2] = 0x6677001122334455ul; - ret = callit((unsigned long)&quad[1], (unsigned long)regs, - (unsigned long)&do_lq_np, msr); - if (ret == 0x600) { - if (mfspr(SPRG0) != (unsigned long) &do_lq_np + 4 || - mfspr(DAR) != (unsigned long) &quad[1]) - return ret | 11; - } else - return 12; - - /* make sure lq with rt = ra causes an illegal instruction interrupt */ - ret = callit((unsigned long)quad, (unsigned long)regs, - (unsigned long)&do_lq_bad, msr); - if (ret != 0x700) - return 13; - if (mfspr(SPRG0) != (unsigned long)&do_lq_bad + 4 || - !(mfspr(SPRG3) & 0x80000)) - return 14; - return 0; -} - -int mode_test_8(void) -{ - unsigned long quad[4] __attribute__((__aligned__(16))); - unsigned long regs[2]; - unsigned long ret, msr; - - /* - * Test lq/stq in BE mode - */ - msr = MSR_SF; - quad[0] = 0x123456789abcdef0ul; - quad[1] = 0xfafa5959bcbc3434ul; - ret = callit((unsigned long)quad, (unsigned long)regs, - (unsigned long)&do_lq_be, msr); - if (ret) - return ret | 1; - if (regs[0] != quad[0] || regs[1] != quad[1]) { - print_hex(regs[0], 16); - print_string(" "); - print_hex(regs[1], 16); - print_string(" "); - return 2; - } - /* don't expect alignment interrupt */ - quad[2] = 0x0011223344556677ul; - ret = callit((unsigned long)&quad[1], (unsigned long)regs, - (unsigned long)&do_lq_be, msr); - if (ret == 0) { - if (regs[0] != quad[1] || regs[1] != quad[2]) - return 3; - } else - return ret | 5; - - /* try stq */ - regs[0] = 0x5238523852385238ul; - regs[1] = 0x5239523952395239ul; - ret = callit((unsigned long)quad, (unsigned long)regs, - (unsigned long)&do_stq_be, msr); - if (ret) - return ret | 5; - if (quad[0] != regs[0] || quad[1] != regs[1]) - return 6; - regs[0] = 0x0172686966746564ul; - regs[1] = 0xfe8d0badd00dabcdul; - ret = callit((unsigned long)quad + 1, (unsigned long)regs, - (unsigned long)&do_stq_be, msr); - if (ret) - return ret | 7; - if (((quad[0] >> 8) | (quad[1] << 56)) != regs[0] || - ((quad[1] >> 8) | (quad[2] << 56)) != regs[1]) { - print_hex(quad[0], 16); - print_string(" "); - print_hex(quad[1], 16); - print_string(" "); - print_hex(quad[2], 16); - print_string(" "); - return 8; - } - - /* try lq non-preferred form */ - quad[0] = 0x56789abcdef01234ul; - quad[1] = 0x5959bcbc3434fafaul; - ret = callit((unsigned long)quad, (unsigned long)regs, - (unsigned long)&do_lq_np_be, msr); - if (ret) - return ret | 9; - if (regs[0] != quad[0] || regs[1] != quad[1]) - return 10; - /* unaligned should not give alignment interrupt in uW implementation */ - quad[2] = 0x6677001122334455ul; - ret = callit((unsigned long)&quad[1], (unsigned long)regs, - (unsigned long)&do_lq_np_be, msr); - if (ret) - return ret | 11; - if (regs[0] != quad[1] || regs[1] != quad[2]) - return 12; - return 0; -} - int fail = 0; void do_test(int num, int (*test)(void)) @@ -507,8 +338,6 @@ int main(void) do_test(4, mode_test_4); do_test(5, mode_test_5); do_test(6, mode_test_6); - do_test(7, mode_test_7); - do_test(8, mode_test_8); return fail; } diff --git a/tests/reservation/head.S b/tests/reservation/head.S index 4ff85ce..ce258b5 100644 --- a/tests/reservation/head.S +++ b/tests/reservation/head.S @@ -155,31 +155,3 @@ call_ret: ld %r31,248(%r1) addi %r1,%r1,256 blr - - .global do_lqarx -do_lqarx: - /* r3 = src, r4 = regs */ - lqarx %r10,0,%r3 - std %r10,0(%r4) - std %r11,8(%r4) - li %r3,0 - blr - - .global do_lqarx_bad -do_lqarx_bad: - /* r3 = src, r4 = regs */ - .long 0x7d405228 /* lqarx %r10,0,%r10 */ - std %r10,0(%r4) - std %r11,8(%r4) - li %r3,0 - blr - - .global do_stqcx -do_stqcx: - /* r3 = dest, r4 = regs, return CR */ - ld %r10,0(%r4) - ld %r11,8(%r4) - stqcx. %r10,0,%r3 - mfcr %r3 - oris %r3,%r3,1 /* to distinguish from trap number */ - blr diff --git a/tests/reservation/reservation.c b/tests/reservation/reservation.c index a3d5a7a..79bbc1f 100644 --- a/tests/reservation/reservation.c +++ b/tests/reservation/reservation.c @@ -7,10 +7,6 @@ extern unsigned long callit(unsigned long arg1, unsigned long arg2, unsigned long (*fn)(unsigned long, unsigned long)); -extern unsigned long do_lqarx(unsigned long src, unsigned long regs); -extern unsigned long do_lqarx_bad(unsigned long src, unsigned long regs); -extern unsigned long do_stqcx(unsigned long dst, unsigned long regs); - #define DSISR 18 #define DAR 19 #define SRR0 26 @@ -184,63 +180,6 @@ int resv_test_2(void) return 0; } -/* test lqarx/stqcx */ -int resv_test_3(void) -{ - unsigned long x[4] __attribute__((__aligned__(16))); - unsigned long y[2], regs[2]; - unsigned long ret, offset; - int count; - - x[0] = 0x7766554433221100ul; - x[1] = 0xffeeddccbbaa9988ul; - y[0] = 0x0badcafef00dd00dul; - y[1] = 0xdeadbeef07070707ul; - for (count = 0; count < 1000; ++count) { - ret = callit((unsigned long)x, (unsigned long)regs, do_lqarx); - if (ret) - return ret | 1; - ret = callit((unsigned long)x, (unsigned long)y, do_stqcx); - if (ret < 0x10000) - return ret | 2; - if (ret & 0x20000000) - break; - } - if (count == 1000) - return 3; - if (x[0] != y[1] || x[1] != y[0]) - return 4; - if (regs[1] != 0x7766554433221100ul || regs[0] != 0xffeeddccbbaa9988ul) - return 5; - ret = callit((unsigned long)x, (unsigned long)regs, do_stqcx); - if (ret < 0x10000 || (ret & 0x20000000)) - return ret | 12; - /* test alignment interrupts */ - for (offset = 0; offset < 16; ++offset) { - ret = callit((unsigned long)x + offset, (unsigned long)regs, do_lqarx); - if (ret == 0 && (offset & 15) != 0) - return 6; - if (ret == 0x600) { - if ((offset & 15) == 0) - return ret + 7; - } else if (ret) - return ret; - ret = callit((unsigned long)x + offset, (unsigned long)y, do_stqcx); - if (ret >= 0x10000 && (offset & 15) != 0) - return 8; - if (ret == 0x600) { - if ((offset & 15) == 0) - return ret + 9; - } else if (ret < 0x10000) - return ret; - } - /* test illegal interrupt for bad lqarx case */ - ret = callit((unsigned long)x, (unsigned long)regs, do_lqarx_bad); - if (ret != 0x700 || !(mfspr(SRR1) & 0x80000)) - return ret + 10; - return 0; -} - int fail = 0; void do_test(int num, int (*test)(void)) @@ -265,7 +204,6 @@ int main(void) do_test(1, resv_test_1); do_test(2, resv_test_2); - do_test(3, resv_test_3); return fail; } diff --git a/tests/test_modes.bin b/tests/test_modes.bin index 7e6b8f5..24e3981 100755 Binary files a/tests/test_modes.bin and b/tests/test_modes.bin differ diff --git a/tests/test_modes.console_out b/tests/test_modes.console_out index 25e791c..a49bb9b 100644 --- a/tests/test_modes.console_out +++ b/tests/test_modes.console_out @@ -4,5 +4,3 @@ test 03:PASS test 04:PASS test 05:PASS test 06:PASS -test 07:PASS -test 08:PASS diff --git a/tests/test_reservation.bin b/tests/test_reservation.bin index 1e305f4..1cb6250 100755 Binary files a/tests/test_reservation.bin and b/tests/test_reservation.bin differ diff --git a/tests/test_reservation.console_out b/tests/test_reservation.console_out index 623335d..0c39ae3 100644 --- a/tests/test_reservation.console_out +++ b/tests/test_reservation.console_out @@ -1,3 +1,2 @@ test 01:PASS test 02:PASS -test 03:PASS