mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-04-05 04:35:00 +00:00
Merge pull request #249 from paulusmack/master
Sundry bug fixes, plus implement mtmsr
This commit is contained in:
@@ -313,6 +313,7 @@ architecture behaviour of decode1 is
|
||||
2#1100001001# => (ALU, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '0'), -- modsd
|
||||
2#1100001011# => (ALU, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '1', NONE, '0', '0'), -- modsw
|
||||
2#0010010000# => (ALU, OP_MTCRF, NONE, NONE, RS, NONE, '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- mtcrf/mtocrf
|
||||
2#0010010010# => (ALU, OP_MTMSRD, NONE, NONE, RS, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', NONE, '0', '1'), -- mtmsr
|
||||
2#0010110010# => (ALU, OP_MTMSRD, NONE, NONE, RS, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mtmsrd # ignore top bits and d
|
||||
2#0111010011# => (ALU, OP_MTSPR, NONE, NONE, RS, SPR, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- mtspr
|
||||
2#0001001001# => (ALU, OP_MUL_H64, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '0'), -- mulhd
|
||||
|
||||
@@ -993,8 +993,11 @@ begin
|
||||
else
|
||||
-- Architecture says to leave out bits 3 (HV), 51 (ME)
|
||||
-- and 63 (LE) (IBM bit numbering)
|
||||
ctrl_tmp.msr(63 downto 61) <= c_in(63 downto 61);
|
||||
ctrl_tmp.msr(59 downto 13) <= c_in(59 downto 13);
|
||||
if e_in.is_32bit = '0' then
|
||||
ctrl_tmp.msr(63 downto 61) <= c_in(63 downto 61);
|
||||
ctrl_tmp.msr(59 downto 32) <= c_in(59 downto 32);
|
||||
end if;
|
||||
ctrl_tmp.msr(31 downto 13) <= c_in(31 downto 13);
|
||||
ctrl_tmp.msr(11 downto 1) <= c_in(11 downto 1);
|
||||
if c_in(MSR_PR) = '1' then
|
||||
ctrl_tmp.msr(MSR_EE) <= '1';
|
||||
@@ -1124,14 +1127,27 @@ begin
|
||||
elsif HAS_FPU and e_in.unit = FPU then
|
||||
fv.valid := '1';
|
||||
end if;
|
||||
-- Handling an ITLB miss doesn't count as having executed an instruction
|
||||
if e_in.insn_type = OP_FETCH_FAILED then
|
||||
do_trace := '0';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
elsif r.f.redirect = '1' then
|
||||
-- The following cases all occur when r.busy = 1 and therefore
|
||||
-- valid_in = 0. Hence they don't happen in the same cycle as any of
|
||||
-- the cases above which depend on valid_in = 1.
|
||||
|
||||
if r.f.redirect = '1' then
|
||||
v.e.valid := '1';
|
||||
elsif r.lr_update = '1' then
|
||||
end if;
|
||||
if r.lr_update = '1' then
|
||||
v.e.exc_write_enable := '1';
|
||||
v.e.exc_write_data := r.next_lr;
|
||||
v.e.exc_write_reg := fast_spr_num(SPR_LR);
|
||||
v.e.valid := '1';
|
||||
-- Keep r.e.write_data unchanged next cycle in case it is needed
|
||||
-- for a forwarded result (e.g. for CTR).
|
||||
result := r.e.write_data;
|
||||
elsif r.cntz_in_progress = '1' then
|
||||
-- cnt[lt]z always takes two cycles
|
||||
result := countzero_result;
|
||||
|
||||
@@ -137,3 +137,28 @@ test_mtpvr:
|
||||
mtlr %r0
|
||||
|
||||
blr
|
||||
|
||||
/* Test that bdnz and bdnzl update CTR and LR correctly */
|
||||
.global test_bdnzl
|
||||
test_bdnzl:
|
||||
mflr %r10
|
||||
mfcr %r11
|
||||
li %r0,0xf8
|
||||
mtctr %r0
|
||||
lis %r0,0x2000
|
||||
mtcr %r0
|
||||
addpcis %r9,0
|
||||
1: bdnztl 27,3f
|
||||
2: bdnzt 14,4f
|
||||
3: nop
|
||||
4: li %r3,1
|
||||
addi %r9,%r9,2b-1b
|
||||
mflr %r8
|
||||
cmpd %r8,%r9
|
||||
bne 9f
|
||||
mfctr %r7
|
||||
cmpdi %r7,0xf6
|
||||
bne 9f
|
||||
li %r3,0
|
||||
9: mtlr %r10
|
||||
blr
|
||||
|
||||
@@ -14,6 +14,7 @@ extern long test_addpcis_1(void);
|
||||
extern long test_addpcis_2(void);
|
||||
extern long test_mfpvr(void);
|
||||
extern long test_mtpvr(void);
|
||||
extern long test_bdnzl(void);
|
||||
|
||||
// i < 100
|
||||
void print_test_number(int i)
|
||||
@@ -58,5 +59,12 @@ int main(void)
|
||||
} else
|
||||
puts(PASS);
|
||||
|
||||
print_test_number(5);
|
||||
if (test_bdnzl() != 0) {
|
||||
fail = 1;
|
||||
puts(FAIL);
|
||||
} else
|
||||
puts(PASS);
|
||||
|
||||
return fail;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -2,3 +2,4 @@ Test 01:PASS
|
||||
Test 02:PASS
|
||||
Test 03:PASS
|
||||
Test 04:PASS
|
||||
Test 05:PASS
|
||||
|
||||
Binary file not shown.
@@ -5,3 +5,4 @@ test 04:PASS
|
||||
test 05:PASS
|
||||
test 06:PASS
|
||||
test 07:PASS
|
||||
test 08:PASS
|
||||
|
||||
@@ -214,3 +214,8 @@ test7:
|
||||
bne 1f
|
||||
li %r3,-1
|
||||
1: blr
|
||||
|
||||
.global test8
|
||||
test8:
|
||||
lfd %f0,0(%r3)
|
||||
blr
|
||||
|
||||
@@ -8,6 +8,7 @@ extern unsigned long callit(unsigned long arg1, unsigned long arg2,
|
||||
unsigned long (*fn)(unsigned long, unsigned long),
|
||||
unsigned long msr, unsigned long *regs);
|
||||
|
||||
#define MSR_FP 0x2000
|
||||
#define MSR_SE 0x400
|
||||
#define MSR_BE 0x200
|
||||
|
||||
@@ -188,6 +189,22 @@ int trace_test_7(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern unsigned long test8(unsigned long, unsigned long);
|
||||
|
||||
int trace_test_8(void)
|
||||
{
|
||||
unsigned long ret;
|
||||
unsigned long regs[2];
|
||||
|
||||
ret = callit(0, 0, test8, (mfmsr() & ~MSR_FP) | MSR_SE, regs);
|
||||
if (ret != 0x800)
|
||||
return ret + 1;
|
||||
ret = callit(0, 0, test8, mfmsr() | MSR_FP | MSR_SE, regs);
|
||||
if (ret != 0xd00)
|
||||
return ret + 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fail = 0;
|
||||
|
||||
void do_test(int num, int (*test)(void))
|
||||
@@ -217,6 +234,7 @@ int main(void)
|
||||
do_test(5, trace_test_5);
|
||||
do_test(6, trace_test_6);
|
||||
do_test(7, trace_test_7);
|
||||
do_test(8, trace_test_8);
|
||||
|
||||
return fail;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user