Merge pull request #249 from paulusmack/master

Sundry bug fixes, plus implement mtmsr
pull/252/head
Michael Neuling 4 years ago committed by GitHub
commit 16da9b5ba7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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;
}

Loading…
Cancel
Save