ARM: Use custom read/write code to alias R15 with the PC.
This commit is contained in:
parent
b8b7c7314a
commit
3e2cad8370
2 changed files with 21 additions and 20 deletions
|
@ -40,16 +40,27 @@ def operand_types {{
|
||||||
'df' : ('float', 64)
|
'df' : ('float', 64)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
let {{
|
||||||
|
maybePCRead = '''
|
||||||
|
((%(reg_idx)s == PCReg) ? (xc->readPC() + 8) :
|
||||||
|
xc->%(func)s(this, %(op_idx)s))
|
||||||
|
'''
|
||||||
|
maybePCWrite = '''
|
||||||
|
((%(reg_idx)s == PCReg) ? xc->setNextPC(%(final_val)s) :
|
||||||
|
xc->%(func)s(this, %(op_idx)s, %(final_val)s))
|
||||||
|
'''
|
||||||
|
}};
|
||||||
|
|
||||||
def operands {{
|
def operands {{
|
||||||
#General Purpose Integer Reg Operands
|
#General Purpose Integer Reg Operands
|
||||||
'Rd': ('IntReg', 'uw', 'RD', 'IsInteger', 1),
|
'Rd': ('IntReg', 'uw', 'RD', 'IsInteger', 1, maybePCRead, maybePCWrite),
|
||||||
'Rm': ('IntReg', 'uw', 'RM', 'IsInteger', 2),
|
'Rm': ('IntReg', 'uw', 'RM', 'IsInteger', 2, maybePCRead, maybePCWrite),
|
||||||
'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 3),
|
'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 3, maybePCRead, maybePCWrite),
|
||||||
'Rn': ('IntReg', 'uw', 'RN', 'IsInteger', 4),
|
'Rn': ('IntReg', 'uw', 'RN', 'IsInteger', 4, maybePCRead, maybePCWrite),
|
||||||
|
|
||||||
#Destination register for load/store double instructions
|
#Destination register for load/store double instructions
|
||||||
'Rdo': ('IntReg', 'uw', '(RD & ~1)', 'IsInteger', 4),
|
'Rdo': ('IntReg', 'uw', '(RD & ~1)', 'IsInteger', 4, maybePCRead, maybePCWrite),
|
||||||
'Rde': ('IntReg', 'uw', '(RD | 1)', 'IsInteger', 5),
|
'Rde': ('IntReg', 'uw', '(RD | 1)', 'IsInteger', 5, maybePCRead, maybePCWrite),
|
||||||
|
|
||||||
'Raddr': ('IntReg', 'uw', '17', 'IsInteger', 6),
|
'Raddr': ('IntReg', 'uw', '17', 'IsInteger', 6),
|
||||||
'Rhi': ('IntReg', 'uw', '18', 'IsInteger', 7),
|
'Rhi': ('IntReg', 'uw', '18', 'IsInteger', 7),
|
||||||
|
@ -57,8 +68,8 @@ def operands {{
|
||||||
'LR': ('IntReg', 'uw', '14', 'IsInteger', 9),
|
'LR': ('IntReg', 'uw', '14', 'IsInteger', 9),
|
||||||
|
|
||||||
#Register fields for microops
|
#Register fields for microops
|
||||||
'Ra' : ('IntReg', 'uw', 'ura', 'IsInteger', 11),
|
'Ra' : ('IntReg', 'uw', 'ura', 'IsInteger', 11, maybePCRead, maybePCWrite),
|
||||||
'Rb' : ('IntReg', 'uw', 'urb', 'IsInteger', 12),
|
'Rb' : ('IntReg', 'uw', 'urb', 'IsInteger', 12, maybePCRead, maybePCWrite),
|
||||||
|
|
||||||
#General Purpose Floating Point Reg Operands
|
#General Purpose Floating Point Reg Operands
|
||||||
'Fd': ('FloatReg', 'df', 'FD', 'IsFloating', 20),
|
'Fd': ('FloatReg', 'df', 'FD', 'IsFloating', 20),
|
||||||
|
|
|
@ -122,21 +122,11 @@ namespace ArmISA
|
||||||
|
|
||||||
IntReg readIntReg(int intReg)
|
IntReg readIntReg(int intReg)
|
||||||
{
|
{
|
||||||
// In the Arm, reading from the PC for a generic instruction yields
|
|
||||||
// the current PC + 8, due to previous pipeline implementations
|
|
||||||
if (intReg == PCReg)
|
|
||||||
return intRegFile.readReg(intReg) + 8;
|
|
||||||
//return pc + 8;
|
|
||||||
else
|
|
||||||
return intRegFile.readReg(intReg);
|
return intRegFile.readReg(intReg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setIntReg(int intReg, const IntReg &val)
|
void setIntReg(int intReg, const IntReg &val)
|
||||||
{
|
{
|
||||||
// Have to trap writes to PC so that they update NPC instead
|
|
||||||
if (intReg == PCReg)
|
|
||||||
setNextPC(val);
|
|
||||||
else
|
|
||||||
intRegFile.setReg(intReg, val);
|
intRegFile.setReg(intReg, val);
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
|
|
Loading…
Reference in a new issue