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
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
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
-- 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
);
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
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))));
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");
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))
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;
}