ARM: Add support for interworking branch ALU instructions.
This commit is contained in:
parent
11c3361be4
commit
e92dc21fde
2 changed files with 89 additions and 46 deletions
|
@ -98,7 +98,7 @@ let {{
|
|||
regOp2 = "shift_rm_imm(Op2, shiftAmt, shiftType, CondCodes<29:>)"
|
||||
regRegOp2 = "shift_rm_rs(Op2, Shift<7:0>, shiftType, CondCodes<29:>)"
|
||||
|
||||
def buildDataInst(mnem, code, flagType = "logic"):
|
||||
def buildImmDataInst(mnem, code, flagType = "logic"):
|
||||
global header_output, decoder_output, exec_output
|
||||
cCode = carryCode[flagType]
|
||||
vCode = overflowCode[flagType]
|
||||
|
@ -106,85 +106,117 @@ let {{
|
|||
if flagType == "llbit":
|
||||
negBit = 63
|
||||
if flagType == "overflow":
|
||||
immCcCode = regCcCode = regRegCcCode = calcQCode
|
||||
immCcCode = calcQCode
|
||||
else:
|
||||
immCcCode = calcCcCode % {
|
||||
"icValue": secondOpRe.sub(immOp2, cCode[0]),
|
||||
"ivValue": secondOpRe.sub(immOp2, vCode),
|
||||
"negBit": negBit
|
||||
}
|
||||
immCode = secondOpRe.sub(immOp2, code)
|
||||
immIop = InstObjParams(mnem, mnem.capitalize() + "Imm", "DataImmOp",
|
||||
{"code" : immCode,
|
||||
"predicate_test": predicateTest})
|
||||
immIopCc = InstObjParams(mnem + "s", mnem.capitalize() + "ImmCc",
|
||||
"DataImmOp",
|
||||
{"code" : immCode + immCcCode,
|
||||
"predicate_test": predicateTest})
|
||||
header_output += DataImmDeclare.subst(immIop) + \
|
||||
DataImmDeclare.subst(immIopCc)
|
||||
decoder_output += DataImmConstructor.subst(immIop) + \
|
||||
DataImmConstructor.subst(immIopCc)
|
||||
exec_output += PredOpExecute.subst(immIop) + \
|
||||
PredOpExecute.subst(immIopCc)
|
||||
|
||||
def buildRegDataInst(mnem, code, flagType = "logic"):
|
||||
global header_output, decoder_output, exec_output
|
||||
cCode = carryCode[flagType]
|
||||
vCode = overflowCode[flagType]
|
||||
negBit = 31
|
||||
if flagType == "llbit":
|
||||
negBit = 63
|
||||
if flagType == "overflow":
|
||||
regCcCode = calcQCode
|
||||
else:
|
||||
regCcCode = calcCcCode % {
|
||||
"icValue": secondOpRe.sub(regOp2, cCode[1]),
|
||||
"ivValue": secondOpRe.sub(regOp2, vCode),
|
||||
"negBit": negBit
|
||||
}
|
||||
regCode = secondOpRe.sub(regOp2, code)
|
||||
regIop = InstObjParams(mnem, mnem.capitalize() + "Reg", "DataRegOp",
|
||||
{"code" : regCode,
|
||||
"predicate_test": predicateTest})
|
||||
regIopCc = InstObjParams(mnem + "s", mnem.capitalize() + "RegCc",
|
||||
"DataRegOp",
|
||||
{"code" : regCode + regCcCode,
|
||||
"predicate_test": predicateTest})
|
||||
header_output += DataRegDeclare.subst(regIop) + \
|
||||
DataRegDeclare.subst(regIopCc)
|
||||
decoder_output += DataRegConstructor.subst(regIop) + \
|
||||
DataRegConstructor.subst(regIopCc)
|
||||
exec_output += PredOpExecute.subst(regIop) + \
|
||||
PredOpExecute.subst(regIopCc)
|
||||
|
||||
def buildRegRegDataInst(mnem, code, flagType = "logic"):
|
||||
global header_output, decoder_output, exec_output
|
||||
cCode = carryCode[flagType]
|
||||
vCode = overflowCode[flagType]
|
||||
negBit = 31
|
||||
if flagType == "llbit":
|
||||
negBit = 63
|
||||
if flagType == "overflow":
|
||||
regRegCcCode = calcQCode
|
||||
else:
|
||||
regRegCcCode = calcCcCode % {
|
||||
"icValue": secondOpRe.sub(regRegOp2, cCode[2]),
|
||||
"ivValue": secondOpRe.sub(regRegOp2, vCode),
|
||||
"negBit": negBit
|
||||
}
|
||||
immCode = secondOpRe.sub(immOp2, code)
|
||||
regCode = secondOpRe.sub(regOp2, code)
|
||||
regRegCode = secondOpRe.sub(regRegOp2, code)
|
||||
immIop = InstObjParams(mnem, mnem.capitalize() + "Imm", "DataImmOp",
|
||||
{"code" : immCode,
|
||||
"predicate_test": predicateTest})
|
||||
regIop = InstObjParams(mnem, mnem.capitalize() + "Reg", "DataRegOp",
|
||||
{"code" : regCode,
|
||||
"predicate_test": predicateTest})
|
||||
regRegIop = InstObjParams(mnem, mnem.capitalize() + "RegReg",
|
||||
"DataRegRegOp",
|
||||
{"code" : regRegCode,
|
||||
"predicate_test": predicateTest})
|
||||
immIopCc = InstObjParams(mnem + "s", mnem.capitalize() + "ImmCc",
|
||||
"DataImmOp",
|
||||
{"code" : immCode + immCcCode,
|
||||
"predicate_test": predicateTest})
|
||||
regIopCc = InstObjParams(mnem + "s", mnem.capitalize() + "RegCc",
|
||||
"DataRegOp",
|
||||
{"code" : regCode + regCcCode,
|
||||
"predicate_test": predicateTest})
|
||||
regRegIopCc = InstObjParams(mnem + "s",
|
||||
mnem.capitalize() + "RegRegCc",
|
||||
"DataRegRegOp",
|
||||
{"code" : regRegCode + regRegCcCode,
|
||||
"predicate_test": predicateTest})
|
||||
header_output += DataImmDeclare.subst(immIop) + \
|
||||
DataImmDeclare.subst(immIopCc) + \
|
||||
DataRegDeclare.subst(regIop) + \
|
||||
DataRegDeclare.subst(regIopCc) + \
|
||||
DataRegRegDeclare.subst(regRegIop) + \
|
||||
header_output += DataRegRegDeclare.subst(regRegIop) + \
|
||||
DataRegRegDeclare.subst(regRegIopCc)
|
||||
decoder_output += DataImmConstructor.subst(immIop) + \
|
||||
DataImmConstructor.subst(immIopCc) + \
|
||||
DataRegConstructor.subst(regIop) + \
|
||||
DataRegConstructor.subst(regIopCc) + \
|
||||
DataRegRegConstructor.subst(regRegIop) + \
|
||||
decoder_output += DataRegRegConstructor.subst(regRegIop) + \
|
||||
DataRegRegConstructor.subst(regRegIopCc)
|
||||
exec_output += PredOpExecute.subst(immIop) + \
|
||||
PredOpExecute.subst(immIopCc) + \
|
||||
PredOpExecute.subst(regIop) + \
|
||||
PredOpExecute.subst(regIopCc) + \
|
||||
PredOpExecute.subst(regRegIop) + \
|
||||
exec_output += PredOpExecute.subst(regRegIop) + \
|
||||
PredOpExecute.subst(regRegIopCc)
|
||||
|
||||
buildDataInst("and", "Dest = resTemp = Op1 & secondOp;")
|
||||
buildDataInst("eor", "Dest = resTemp = Op1 ^ secondOp;")
|
||||
buildDataInst("sub", "Dest = resTemp = Op1 - secondOp;", "sub")
|
||||
buildDataInst("rsb", "Dest = resTemp = secondOp - Op1;", "rsb")
|
||||
buildDataInst("add", "Dest = resTemp = Op1 + secondOp;", "add")
|
||||
buildDataInst("adc", "Dest = resTemp = Op1 + secondOp + %s;" % oldC, "add")
|
||||
buildDataInst("sbc", "Dest = resTemp = Op1 - secondOp - !%s;" % oldC, "sub")
|
||||
buildDataInst("rsc", "Dest = resTemp = secondOp - Op1 - !%s;" % oldC, "rsb")
|
||||
def buildDataInst(mnem, code, flagType = "logic"):
|
||||
buildImmDataInst(mnem, code, flagType)
|
||||
buildRegDataInst(mnem, code, flagType)
|
||||
buildRegRegDataInst(mnem, code, flagType)
|
||||
|
||||
buildDataInst("and", "AIWDest = resTemp = Op1 & secondOp;")
|
||||
buildDataInst("eor", "AIWDest = resTemp = Op1 ^ secondOp;")
|
||||
buildDataInst("sub", "AIWDest = resTemp = Op1 - secondOp;", "sub")
|
||||
buildDataInst("rsb", "AIWDest = resTemp = secondOp - Op1;", "rsb")
|
||||
buildDataInst("add", "AIWDest = resTemp = Op1 + secondOp;", "add")
|
||||
buildDataInst("adc", "AIWDest = resTemp = Op1 + secondOp + %s;" % oldC,
|
||||
"add")
|
||||
buildDataInst("sbc", "AIWDest = resTemp = Op1 - secondOp - !%s;" % oldC,
|
||||
"sub")
|
||||
buildDataInst("rsc", "AIWDest = resTemp = secondOp - Op1 - !%s;" % oldC,
|
||||
"rsb")
|
||||
buildDataInst("tst", "resTemp = Op1 & secondOp;")
|
||||
buildDataInst("teq", "resTemp = Op1 ^ secondOp;")
|
||||
buildDataInst("cmp", "resTemp = Op1 - secondOp;", "sub")
|
||||
buildDataInst("cmn", "resTemp = Op1 + secondOp;", "add")
|
||||
buildDataInst("orr", "Dest = resTemp = Op1 | secondOp;")
|
||||
buildDataInst("orr", "AIWDest = resTemp = Op1 | secondOp;")
|
||||
buildDataInst("orn", "Dest = resTemp = Op1 | ~secondOp;")
|
||||
buildDataInst("mov", "Dest = resTemp = secondOp;")
|
||||
buildDataInst("bic", "Dest = resTemp = Op1 & ~secondOp;")
|
||||
buildDataInst("mvn", "Dest = resTemp = ~secondOp;")
|
||||
buildImmDataInst("mov", "AIWDest = resTemp = secondOp;")
|
||||
buildRegDataInst("mov", "AIWDest = resTemp = secondOp;")
|
||||
buildRegRegDataInst("mov", "Dest = resTemp = secondOp;")
|
||||
buildDataInst("bic", "AIWDest = resTemp = Op1 & ~secondOp;")
|
||||
buildDataInst("mvn", "AIWDest = resTemp = ~secondOp;")
|
||||
buildDataInst("movt",
|
||||
"Dest = resTemp = insertBits(Op1, 31, 16, secondOp);")
|
||||
}};
|
||||
|
|
|
@ -64,6 +64,17 @@ let {{
|
|||
((%(reg_idx)s == PCReg) ? setIWNextPC(xc, %(final_val)s) :
|
||||
xc->%(func)s(this, %(op_idx)s, %(final_val)s))
|
||||
'''
|
||||
maybeAIWPCWrite = '''
|
||||
if (%(reg_idx)s == PCReg) {
|
||||
if (xc->readPC() & (ULL(1) << PcTBitShift)) {
|
||||
setIWNextPC(xc, %(final_val)s);
|
||||
} else {
|
||||
setNextPC(xc, %(final_val)s);
|
||||
}
|
||||
} else {
|
||||
xc->%(func)s(this, %(op_idx)s, %(final_val)s);
|
||||
}
|
||||
'''
|
||||
|
||||
readNPC = 'xc->readNextPC() & ~PcModeMask'
|
||||
writeNPC = 'setNextPC(xc, %(final_val)s)'
|
||||
|
@ -78,7 +89,7 @@ def operands {{
|
|||
'IWDest': ('IntReg', 'uw', 'dest', 'IsInteger', 0,
|
||||
maybePCRead, maybeIWPCWrite),
|
||||
'AIWDest': ('IntReg', 'uw', 'dest', 'IsInteger', 0,
|
||||
maybePCRead, maybeIWPCWrite),
|
||||
maybePCRead, maybeAIWPCWrite),
|
||||
'Base': ('IntReg', 'uw', 'base', 'IsInteger', 1,
|
||||
maybePCRead, maybePCWrite),
|
||||
'Index': ('IntReg', 'uw', 'index', 'IsInteger', 2,
|
||||
|
|
Loading…
Reference in a new issue