ARM: Make DataOps select from a set of ways to set the c and v flags.
This commit is contained in:
parent
148c265cf3
commit
26c70ce2cb
3 changed files with 66 additions and 73 deletions
|
@ -83,31 +83,27 @@ format DataOp {
|
||||||
1: decode MISC_OPCODE {
|
1: decode MISC_OPCODE {
|
||||||
0x9: decode PREPOST {
|
0x9: decode PREPOST {
|
||||||
0: decode OPCODE {
|
0: decode OPCODE {
|
||||||
0x0: mul({{ Rn = resTemp = Rm * Rs; }},
|
0x0: mul({{ Rn = resTemp = Rm * Rs; }}, none);
|
||||||
{{ Cpsr<29:> }},
|
0x1: mla({{ Rn = resTemp = Rm * Rs; }}, none);
|
||||||
{{ Cpsr<28:> }});
|
|
||||||
0x1: mla({{ Rn = resTemp = Rm * Rs; }},
|
|
||||||
{{ Cpsr<29:> }},
|
|
||||||
{{ Cpsr<28:> }});
|
|
||||||
0x2: WarnUnimpl::umall();
|
0x2: WarnUnimpl::umall();
|
||||||
0x4: umull({{
|
0x4: umull({{
|
||||||
resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
|
resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
|
||||||
Rd = (uint32_t)(resTemp & 0xffffffff);
|
Rd = (uint32_t)(resTemp & 0xffffffff);
|
||||||
Rn = (uint32_t)(resTemp >> 32);
|
Rn = (uint32_t)(resTemp >> 32);
|
||||||
}}, {{ 1 }}, {{ 1 }});
|
}});
|
||||||
0x5: WarnUnimpl::smlal();
|
0x5: WarnUnimpl::smlal();
|
||||||
0x6: smull({{
|
0x6: smull({{
|
||||||
resTemp = ((int64_t)(int32_t)Rm)*
|
resTemp = ((int64_t)(int32_t)Rm)*
|
||||||
((int64_t)(int32_t)Rs);
|
((int64_t)(int32_t)Rs);
|
||||||
Rd = (int32_t)(resTemp & 0xffffffff);
|
Rd = (int32_t)(resTemp & 0xffffffff);
|
||||||
Rn = (int32_t)(resTemp >> 32);
|
Rn = (int32_t)(resTemp >> 32);
|
||||||
}}, {{ 1 }}, {{ 1 }});
|
}});
|
||||||
0x7: umlal({{
|
0x7: umlal({{
|
||||||
resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
|
resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
|
||||||
resTemp += ((uint64_t)Rn << 32)+((uint64_t)Rd);
|
resTemp += ((uint64_t)Rn << 32)+((uint64_t)Rd);
|
||||||
Rd = (uint32_t)(resTemp & 0xffffffff);
|
Rd = (uint32_t)(resTemp & 0xffffffff);
|
||||||
Rn = (uint32_t)(resTemp >> 32);
|
Rn = (uint32_t)(resTemp >> 32);
|
||||||
}}, {{ 1 }}, {{ 1 }});
|
}});
|
||||||
}
|
}
|
||||||
1: decode PUBWL {
|
1: decode PUBWL {
|
||||||
0x10: WarnUnimpl::swp();
|
0x10: WarnUnimpl::swp();
|
||||||
|
@ -229,32 +225,16 @@ format DataOp {
|
||||||
0: decode OPCODE {
|
0: decode OPCODE {
|
||||||
0x0: and({{ Rd = resTemp = Rn & op2; }});
|
0x0: and({{ Rd = resTemp = Rn & op2; }});
|
||||||
0x1: eor({{ Rd = resTemp = Rn ^ op2; }});
|
0x1: eor({{ Rd = resTemp = Rn ^ op2; }});
|
||||||
0x2: sub({{ Rd = resTemp = Rn - op2; }},
|
0x2: sub({{ Rd = resTemp = Rn - op2; }}, sub);
|
||||||
{{ arm_sub_carry(resTemp, Rn, op2) }},
|
0x3: rsb({{ Rd = resTemp = op2 - Rn; }}, rsb);
|
||||||
{{ arm_sub_overflow(resTemp, Rn, op2) }});
|
0x4: add({{ Rd = resTemp = Rn + op2; }}, add);
|
||||||
0x3: rsb({{ Rd = resTemp = op2 - Rn; }},
|
0x5: adc({{ Rd = resTemp = Rn + op2 + Cpsr<29:>; }}, add);
|
||||||
{{ arm_sub_carry(resTemp, op2, Rn) }},
|
0x6: sbc({{ Rd = resTemp = Rn - op2 - !Cpsr<29:>; }}, sub);
|
||||||
{{ arm_sub_overflow(resTemp, op2, Rn) }});
|
0x7: rsc({{ Rd = resTemp = op2 - Rn - !Cpsr<29:>; }}, rsb);
|
||||||
0x4: add({{ Rd = resTemp = Rn + op2; }},
|
|
||||||
{{ arm_add_carry(resTemp, Rn, op2) }},
|
|
||||||
{{ arm_add_overflow(resTemp, Rn, op2) }});
|
|
||||||
0x5: adc({{ Rd = resTemp = Rn + op2 + Cpsr<29:>; }},
|
|
||||||
{{ arm_add_carry(resTemp, Rn, op2) }},
|
|
||||||
{{ arm_add_overflow(resTemp, Rn, op2) }});
|
|
||||||
0x6: sbc({{ Rd = resTemp = Rn - op2 - !Cpsr<29:>; }},
|
|
||||||
{{ arm_sub_carry(resTemp, Rn, op2) }},
|
|
||||||
{{ arm_sub_overflow(resTemp, Rn, op2) }});
|
|
||||||
0x7: rsc({{ Rd = resTemp = op2 - Rn - !Cpsr<29:>; }},
|
|
||||||
{{ arm_sub_carry(resTemp, op2, Rn) }},
|
|
||||||
{{ arm_sub_overflow(resTemp, op2, Rn) }});
|
|
||||||
0x8: tst({{ resTemp = Rn & op2; }});
|
0x8: tst({{ resTemp = Rn & op2; }});
|
||||||
0x9: teq({{ resTemp = Rn ^ op2; }});
|
0x9: teq({{ resTemp = Rn ^ op2; }});
|
||||||
0xa: cmp({{ resTemp = Rn - op2; }},
|
0xa: cmp({{ resTemp = Rn - op2; }}, sub);
|
||||||
{{ arm_sub_carry(resTemp, Rn, op2) }},
|
0xb: cmn({{ resTemp = Rn + op2; }}, add);
|
||||||
{{ arm_sub_overflow(resTemp, Rn, op2) }});
|
|
||||||
0xb: cmn({{ resTemp = Rn + op2; }},
|
|
||||||
{{ arm_add_carry(resTemp, Rn, op2) }},
|
|
||||||
{{ arm_add_overflow(resTemp, Rn, op2) }});
|
|
||||||
0xc: orr({{ Rd = resTemp = Rn | op2; }});
|
0xc: orr({{ Rd = resTemp = Rn | op2; }});
|
||||||
0xd: mov({{ Rd = resTemp = op2; }});
|
0xd: mov({{ Rd = resTemp = op2; }});
|
||||||
0xe: bic({{ Rd = resTemp = Rn & ~op2; }});
|
0xe: bic({{ Rd = resTemp = Rn & ~op2; }});
|
||||||
|
@ -318,32 +298,16 @@ format DataOp {
|
||||||
format DataImmOp {
|
format DataImmOp {
|
||||||
0x0: andi({{ Rd = resTemp = Rn & rotated_imm; }});
|
0x0: andi({{ Rd = resTemp = Rn & rotated_imm; }});
|
||||||
0x1: eori({{ Rd = resTemp = Rn ^ rotated_imm; }});
|
0x1: eori({{ Rd = resTemp = Rn ^ rotated_imm; }});
|
||||||
0x2: subi({{ Rd = resTemp = Rn - rotated_imm; }},
|
0x2: subi({{ Rd = resTemp = Rn - rotated_imm; }}, sub);
|
||||||
{{ arm_sub_carry(resTemp, Rn, rotated_imm) }},
|
0x3: rsbi({{ Rd = resTemp = rotated_imm - Rn; }}, rsb);
|
||||||
{{ arm_sub_overflow(resTemp, Rn, rotated_imm) }});
|
0x4: addi({{ Rd = resTemp = Rn + rotated_imm; }}, add);
|
||||||
0x3: rsbi({{ Rd = resTemp = rotated_imm - Rn; }},
|
0x5: adci({{ Rd = resTemp = Rn + rotated_imm + Cpsr<29:>; }}, add);
|
||||||
{{ arm_sub_carry(resTemp, rotated_imm, Rn) }},
|
0x6: sbci({{ Rd = resTemp = Rn -rotated_imm - !Cpsr<29:>; }}, sub);
|
||||||
{{ arm_sub_overflow(resTemp, rotated_imm, Rn) }});
|
0x7: rsci({{ Rd = resTemp = rotated_imm - Rn - !Cpsr<29:>;}}, rsb);
|
||||||
0x4: addi({{ Rd = resTemp = Rn + rotated_imm; }},
|
|
||||||
{{ arm_add_carry(resTemp, Rn, rotated_imm) }},
|
|
||||||
{{ arm_add_overflow(resTemp, Rn, rotated_imm) }});
|
|
||||||
0x5: adci({{ Rd = resTemp = Rn + rotated_imm + Cpsr<29:>; }},
|
|
||||||
{{ arm_add_carry(resTemp, Rn, rotated_imm) }},
|
|
||||||
{{ arm_add_overflow(resTemp, Rn, rotated_imm) }});
|
|
||||||
0x6: sbci({{ Rd = resTemp = Rn -rotated_imm - !Cpsr<29:>; }},
|
|
||||||
{{ arm_sub_carry(resTemp, Rn, rotated_imm) }},
|
|
||||||
{{ arm_sub_overflow(resTemp, Rn, rotated_imm) }});
|
|
||||||
0x7: rsci({{ Rd = resTemp = rotated_imm - Rn - !Cpsr<29:>;}},
|
|
||||||
{{ arm_sub_carry(resTemp, rotated_imm, Rn) }},
|
|
||||||
{{ arm_sub_overflow(resTemp, rotated_imm, Rn) }});
|
|
||||||
0x8: tsti({{ resTemp = Rn & rotated_imm; }});
|
0x8: tsti({{ resTemp = Rn & rotated_imm; }});
|
||||||
0x9: teqi({{ resTemp = Rn ^ rotated_imm; }});
|
0x9: teqi({{ resTemp = Rn ^ rotated_imm; }});
|
||||||
0xa: cmpi({{ resTemp = Rn - rotated_imm; }},
|
0xa: cmpi({{ resTemp = Rn - rotated_imm; }}, sub);
|
||||||
{{ arm_sub_carry(resTemp, Rn, rotated_imm) }},
|
0xb: cmni({{ resTemp = Rn + rotated_imm; }}, add);
|
||||||
{{ arm_sub_overflow(resTemp, Rn, rotated_imm) }});
|
|
||||||
0xb: cmni({{ resTemp = Rn + rotated_imm; }},
|
|
||||||
{{ arm_add_carry(resTemp, Rn, rotated_imm) }},
|
|
||||||
{{ arm_add_overflow(resTemp, Rn, rotated_imm) }});
|
|
||||||
0xc: orri({{ Rd = resTemp = Rn | rotated_imm; }});
|
0xc: orri({{ Rd = resTemp = Rn | rotated_imm; }});
|
||||||
0xd: movi({{ Rd = resTemp = rotated_imm; }});
|
0xd: movi({{ Rd = resTemp = rotated_imm; }});
|
||||||
0xe: bici({{ Rd = resTemp = Rn & ~rotated_imm; }});
|
0xe: bici({{ Rd = resTemp = Rn & ~rotated_imm; }});
|
||||||
|
|
|
@ -101,24 +101,54 @@ let {{
|
||||||
|
|
||||||
}};
|
}};
|
||||||
|
|
||||||
def format DataOp(code, icValue = {{ }},
|
let {{
|
||||||
ivValue = {{ Cpsr<28:> }}) {{
|
def getCcCode(flagtype):
|
||||||
|
icReg = icImm = iv = ''
|
||||||
|
if flagtype == "none":
|
||||||
|
icReg = icImm = iv = '1'
|
||||||
|
elif flagtype == "add":
|
||||||
|
icReg = icImm = 'findCarry(32, resTemp, Rn, op2)'
|
||||||
|
iv = 'findOverflow(32, resTemp, Rn, op2)'
|
||||||
|
elif flagtype == "sub":
|
||||||
|
icReg = icImm ='findCarry(32, resTemp, Rn, ~op2)'
|
||||||
|
iv = 'findOverflow(32, resTemp, Rn, ~op2)'
|
||||||
|
elif flagtype == "rsb":
|
||||||
|
icReg = icImm = 'findCarry(32, resTemp, op2, ~Rn)'
|
||||||
|
iv = 'findOverflow(32, resTemp, op2, ~Rn)'
|
||||||
|
else:
|
||||||
|
icReg = 'shift_carry_rs(Rm, Rs, shift, Cpsr<29:>)'
|
||||||
|
icImm = 'shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>)'
|
||||||
|
iv = 'Cpsr<28:>'
|
||||||
|
return (calcCcCode % {"icValue" : icReg, "ivValue" : iv},
|
||||||
|
calcCcCode % {"icValue" : icImm, "ivValue" : iv})
|
||||||
|
|
||||||
|
def getImmCcCode(flagtype):
|
||||||
|
ivValue = icValue = ''
|
||||||
|
if flagtype == "none":
|
||||||
|
icValue = ivValue = '1'
|
||||||
|
elif flagtype == "add":
|
||||||
|
icValue = 'findCarry(32, resTemp, Rn, rotated_imm)'
|
||||||
|
ivValue = 'findOverflow(32, resTemp, Rn, rotated_imm)'
|
||||||
|
elif flagtype == "sub":
|
||||||
|
icValue = 'findCarry(32, resTemp, Rn, ~rotated_imm)'
|
||||||
|
ivValue = 'findOverflow(32, resTemp, Rn, ~rotated_imm)'
|
||||||
|
elif flagtype == "rsb":
|
||||||
|
icValue = 'findCarry(32, resTemp, rotated_imm, ~Rn)'
|
||||||
|
ivValue = 'findOverflow(32, resTemp, rotated_imm, ~Rn)'
|
||||||
|
else:
|
||||||
|
icValue = '(rotate ? rotated_carry:Cpsr<29:>)'
|
||||||
|
ivValue = 'Cpsr<28:>'
|
||||||
|
return calcCcCode % vars()
|
||||||
|
}};
|
||||||
|
|
||||||
|
def format DataOp(code, flagtype = logic) {{
|
||||||
|
(regCcCode, immCcCode) = getCcCode(flagtype)
|
||||||
regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs,
|
regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs,
|
||||||
shift, Cpsr<29:0>);
|
shift, Cpsr<29:0>);
|
||||||
op2 = op2;''' + code
|
op2 = op2;''' + code
|
||||||
immCode = '''uint32_t op2 = shift_rm_imm(Rm, shift_size,
|
immCode = '''uint32_t op2 = shift_rm_imm(Rm, shift_size,
|
||||||
shift, Cpsr<29:0>);
|
shift, Cpsr<29:0>);
|
||||||
op2 = op2;''' + code
|
op2 = op2;''' + code
|
||||||
if icValue == " ":
|
|
||||||
icValueReg = 'shift_carry_rs(Rm, Rs, shift, Cpsr<29:>)'
|
|
||||||
icValueImm = 'shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>)'
|
|
||||||
else:
|
|
||||||
icValueReg = icValue
|
|
||||||
icValueImm = icValue
|
|
||||||
regCcCode = calcCcCode % {"icValue" : icValueReg,
|
|
||||||
"ivValue" : ivValue}
|
|
||||||
immCcCode = calcCcCode % {"icValue" : icValueImm,
|
|
||||||
"ivValue" : ivValue}
|
|
||||||
regIop = InstObjParams(name, Name, 'PredIntOp',
|
regIop = InstObjParams(name, Name, 'PredIntOp',
|
||||||
{"code": regCode,
|
{"code": regCode,
|
||||||
"predicate_test": predicateTest})
|
"predicate_test": predicateTest})
|
||||||
|
@ -146,15 +176,13 @@ def format DataOp(code, icValue = {{ }},
|
||||||
decode_block = DataDecode.subst(regIop)
|
decode_block = DataDecode.subst(regIop)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
def format DataImmOp(code,
|
def format DataImmOp(code, flagtype = logic) {{
|
||||||
icValue = {{ (rotate ? rotated_carry:Cpsr<29:>) }},
|
|
||||||
ivValue = {{ Cpsr<28:> }}) {{
|
|
||||||
code += "resTemp = resTemp;"
|
code += "resTemp = resTemp;"
|
||||||
iop = InstObjParams(name, Name, 'PredImmOp',
|
iop = InstObjParams(name, Name, 'PredImmOp',
|
||||||
{"code": code,
|
{"code": code,
|
||||||
"predicate_test": predicateTest})
|
"predicate_test": predicateTest})
|
||||||
ccIop = InstObjParams(name, Name + "Cc", 'PredImmOp',
|
ccIop = InstObjParams(name, Name + "Cc", 'PredImmOp',
|
||||||
{"code": code + calcCcCode % vars(),
|
{"code": code + getImmCcCode(flagtype),
|
||||||
"predicate_test": predicateTest})
|
"predicate_test": predicateTest})
|
||||||
header_output = BasicDeclare.subst(iop) + \
|
header_output = BasicDeclare.subst(iop) + \
|
||||||
BasicDeclare.subst(ccIop)
|
BasicDeclare.subst(ccIop)
|
||||||
|
|
|
@ -69,6 +69,7 @@ output exec {{
|
||||||
#include "arch/arm/faults.hh"
|
#include "arch/arm/faults.hh"
|
||||||
#include "arch/arm/isa_traits.hh"
|
#include "arch/arm/isa_traits.hh"
|
||||||
#include "arch/arm/utility.hh"
|
#include "arch/arm/utility.hh"
|
||||||
|
#include "base/condcodes.hh"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#if defined(linux)
|
#if defined(linux)
|
||||||
|
|
Loading…
Reference in a new issue