ARM: Fix some bugs in the ISA desc and fill out some instructions.
This commit is contained in:
parent
850eb54a7c
commit
5524af83ef
5 changed files with 98 additions and 41 deletions
|
@ -43,6 +43,7 @@ def bitfield OPCODE_23_20 opcode23_20;
|
|||
def bitfield OPCODE_23_21 opcode23_21;
|
||||
def bitfield OPCODE_22 opcode22;
|
||||
def bitfield OPCODE_19 opcode19;
|
||||
def bitfield OPCODE_18 opcode18;
|
||||
def bitfield OPCODE_15_12 opcode15_12;
|
||||
def bitfield OPCODE_15 opcode15;
|
||||
def bitfield MISC_OPCODE miscOpcode;
|
||||
|
|
|
@ -51,20 +51,25 @@ format DataOp {
|
|||
resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
|
||||
Rd = (uint32_t)(resTemp & 0xffffffff);
|
||||
Rn = (uint32_t)(resTemp >> 32);
|
||||
}});
|
||||
0x5: WarnUnimpl::smlal();
|
||||
}}, llbit);
|
||||
0x5: smlal({{
|
||||
resTemp = ((int64_t)Rm) * ((int64_t)Rs);
|
||||
resTemp += (((uint64_t)Rn) << 32) | ((uint64_t)Rd);
|
||||
Rd = (uint32_t)(resTemp & 0xffffffff);
|
||||
Rn = (uint32_t)(resTemp >> 32);
|
||||
}}, llbit);
|
||||
0x6: smull({{
|
||||
resTemp = ((int64_t)(int32_t)Rm)*
|
||||
((int64_t)(int32_t)Rs);
|
||||
Rd = (int32_t)(resTemp & 0xffffffff);
|
||||
Rn = (int32_t)(resTemp >> 32);
|
||||
}});
|
||||
}}, llbit);
|
||||
0x7: umlal({{
|
||||
resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
|
||||
resTemp += ((uint64_t)Rn << 32)+((uint64_t)Rd);
|
||||
Rd = (uint32_t)(resTemp & 0xffffffff);
|
||||
Rn = (uint32_t)(resTemp >> 32);
|
||||
}});
|
||||
}}, llbit);
|
||||
}
|
||||
1: decode PUBWL {
|
||||
0x10: WarnUnimpl::swp();
|
||||
|
@ -105,9 +110,17 @@ format DataOp {
|
|||
}
|
||||
1: decode MISC_OPCODE {
|
||||
0x0: decode OPCODE {
|
||||
0x8: WarnUnimpl::mrs_cpsr();
|
||||
0x9: WarnUnimpl::msr_cpsr();
|
||||
0xa: WarnUnimpl::mrs_spsr();
|
||||
0x8: PredOp::mrs_cpsr({{ Rd = Cpsr | CondCodes; }});
|
||||
0x9: PredOp::msr_cpsr({{
|
||||
//assert(!RN<1:0>);
|
||||
if (OPCODE_18) {
|
||||
Cpsr = Cpsr<31:20> | mbits(Rm, 19, 16) | Cpsr<15:0>;
|
||||
}
|
||||
if (OPCODE_19) {
|
||||
CondCodes = mbits(Rm, 31,27);
|
||||
}
|
||||
}});
|
||||
0xa: PredOp::mrs_spsr({{ Rd = 0; // should be SPSR}});
|
||||
0xb: WarnUnimpl::msr_spsr();
|
||||
}
|
||||
0x1: decode OPCODE {
|
||||
|
@ -129,28 +142,32 @@ format DataOp {
|
|||
0xb: WarnUnimpl::qdsub();
|
||||
}
|
||||
0x8: decode OPCODE {
|
||||
0x8: WarnUnimpl::smlabb();
|
||||
0x8: smlabb({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<15:0>) + Rd; }}, overflow);
|
||||
0x9: WarnUnimpl::smlalbb();
|
||||
0xa: WarnUnimpl::smlawb();
|
||||
0xb: WarnUnimpl::smulbb();
|
||||
0xb: smulbb({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<15:0>); }}, none);
|
||||
}
|
||||
0xa: decode OPCODE {
|
||||
0x8: WarnUnimpl::smlatb();
|
||||
0x9: WarnUnimpl::smulwb();
|
||||
0x8: smlatb({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<15:0>) + Rd; }}, overflow);
|
||||
0x9: smulwb({{
|
||||
Rn = resTemp = bits(sext<32>(Rm) * sext<16>(Rs<15:0>), 47, 16);
|
||||
}}, none);
|
||||
0xa: WarnUnimpl::smlaltb();
|
||||
0xb: WarnUnimpl::smultb();
|
||||
0xb: smultb({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<15:0>); }}, none);
|
||||
}
|
||||
0xc: decode OPCODE {
|
||||
0x8: WarnUnimpl::smlabt();
|
||||
0x8: smlabt({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<31:16>) + Rd; }}, overflow);
|
||||
0x9: WarnUnimpl::smlawt();
|
||||
0xa: WarnUnimpl::smlalbt();
|
||||
0xb: WarnUnimpl::smulbt();
|
||||
0xb: smulbt({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<31:16>); }}, none);
|
||||
}
|
||||
0xe: decode OPCODE {
|
||||
0x8: WarnUnimpl::smlatt();
|
||||
0x9: WarnUnimpl::smulwt();
|
||||
0x8: smlatt({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<31:16>) + Rd; }}, overflow);
|
||||
0x9: smulwt({{
|
||||
Rn = resTemp = bits(sext<32>(Rm) * sext<16>(Rs<31:16>), 47, 16);
|
||||
}}, none);
|
||||
0xa: WarnUnimpl::smlaltt();
|
||||
0xb: WarnUnimpl::smultt();
|
||||
0xb: smultt({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<31:16>); }}, none);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -184,8 +201,16 @@ format DataOp {
|
|||
}
|
||||
1: decode OPCODE {
|
||||
// The following two instructions aren't supposed to be defined
|
||||
0x8: WarnUnimpl::undefined_instruction();
|
||||
0x9: WarnUnimpl::undefined_instruction();
|
||||
0x8: DataOp::movw({{ Rd = IMMED_11_0 | (RN << 12) ; }});
|
||||
0x9: DataImmOp::msr_ia_cpsr ({{
|
||||
//assert(!RN<1:0>);
|
||||
if (OPCODE_18) {
|
||||
Cpsr = Cpsr<31:20> | rotated_imm | Cpsr<15:0>;
|
||||
}
|
||||
if (OPCODE_19) {
|
||||
CondCodes = rotated_imm;
|
||||
}
|
||||
}});
|
||||
|
||||
0xa: WarnUnimpl::mrs_i_cpsr();
|
||||
0xb: WarnUnimpl::mrs_i_spsr();
|
||||
|
@ -440,6 +465,7 @@ format DataOp {
|
|||
}
|
||||
}
|
||||
}
|
||||
0xf: WarnUnimpl::mcr_cp15();
|
||||
}
|
||||
format PredOp {
|
||||
// ARM System Call (SoftWare Interrupt)
|
||||
|
|
|
@ -81,32 +81,45 @@ def template DataImmDecode {{
|
|||
}};
|
||||
|
||||
let {{
|
||||
|
||||
calcCcCode = '''
|
||||
if (%(canOverflow)s){
|
||||
cprintf("canOverflow: %%d\\n", Rd < resTemp);
|
||||
replaceBits(CondCodes, 27, Rd < resTemp);
|
||||
} else {
|
||||
uint16_t _ic, _iv, _iz, _in;
|
||||
_in = (resTemp >> %(negBit)d) & 1;
|
||||
_iz = (resTemp == 0);
|
||||
_iv = %(ivValue)s & 1;
|
||||
_ic = %(icValue)s & 1;
|
||||
|
||||
CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
|
||||
(CondCodes & 0x0FFFFFFF);
|
||||
|
||||
calcCcCode = '''
|
||||
uint16_t _ic, _iv, _iz, _in;
|
||||
|
||||
_in = (resTemp >> 31) & 1;
|
||||
_iz = (resTemp == 0);
|
||||
_iv = %(ivValue)s & 1;
|
||||
_ic = %(icValue)s & 1;
|
||||
|
||||
CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
|
||||
(CondCodes & 0x0FFFFFFF);
|
||||
|
||||
DPRINTF(Arm, "in = %%d\\n", _in);
|
||||
DPRINTF(Arm, "iz = %%d\\n", _iz);
|
||||
DPRINTF(Arm, "ic = %%d\\n", _ic);
|
||||
DPRINTF(Arm, "iv = %%d\\n", _iv);
|
||||
DPRINTF(Arm, "in = %%d\\n", _in);
|
||||
DPRINTF(Arm, "iz = %%d\\n", _iz);
|
||||
DPRINTF(Arm, "ic = %%d\\n", _ic);
|
||||
DPRINTF(Arm, "iv = %%d\\n", _iv);
|
||||
}
|
||||
'''
|
||||
|
||||
}};
|
||||
|
||||
let {{
|
||||
def getCcCode(flagtype):
|
||||
icReg = icImm = iv = ''
|
||||
negBit = 31
|
||||
canOverflow = 'false'
|
||||
|
||||
if flagtype == "none":
|
||||
icReg = icImm = 'CondCodes<29:>'
|
||||
iv = 'CondCodes<28:>'
|
||||
elif flagtype == "llbit":
|
||||
icReg = icImm = 'CondCodes<29:>'
|
||||
iv = 'CondCodes<28:>'
|
||||
negBit = 63
|
||||
elif flagtype == "overflow":
|
||||
canOverflow = "true"
|
||||
icReg = icImm = iv = '0'
|
||||
elif flagtype == "add":
|
||||
icReg = icImm = 'findCarry(32, resTemp, Rn, op2)'
|
||||
iv = 'findOverflow(32, resTemp, Rn, op2)'
|
||||
|
@ -117,17 +130,32 @@ let {{
|
|||
icReg = icImm = 'findCarry(32, resTemp, op2, ~Rn)'
|
||||
iv = 'findOverflow(32, resTemp, op2, ~Rn)'
|
||||
else:
|
||||
icReg = 'shift_carry_rs(Rm, Rs, shift, CondCodes<29:>)'
|
||||
icReg = 'shift_carry_rs(Rm, Rs<7:0>, shift, CondCodes<29:>)'
|
||||
icImm = 'shift_carry_imm(Rm, shift_size, shift, CondCodes<29:>)'
|
||||
iv = 'CondCodes<28:>'
|
||||
return (calcCcCode % {"icValue" : icReg, "ivValue" : iv},
|
||||
calcCcCode % {"icValue" : icImm, "ivValue" : iv})
|
||||
return (calcCcCode % {"icValue" : icReg,
|
||||
"ivValue" : iv,
|
||||
"negBit" : negBit,
|
||||
"canOverflow" : canOverflow },
|
||||
calcCcCode % {"icValue" : icImm,
|
||||
"ivValue" : iv,
|
||||
"negBit" : negBit,
|
||||
"canOverflow" : canOverflow })
|
||||
|
||||
def getImmCcCode(flagtype):
|
||||
ivValue = icValue = ''
|
||||
negBit = 31
|
||||
canOverflow = 'false'
|
||||
if flagtype == "none":
|
||||
icValue = 'CondCodes<29:>'
|
||||
ivValue = 'CondCodes<28:>'
|
||||
elif flagtype == "llbit":
|
||||
icValue = 'CondCodes<29:>'
|
||||
ivValue = 'CondCodes<28:>'
|
||||
negBit = 63
|
||||
elif flagtype == "overflow":
|
||||
icVaule = ivValue = '0'
|
||||
canOverflow = "true"
|
||||
elif flagtype == "add":
|
||||
icValue = 'findCarry(32, resTemp, Rn, rotated_imm)'
|
||||
ivValue = 'findOverflow(32, resTemp, Rn, rotated_imm)'
|
||||
|
@ -145,11 +173,11 @@ let {{
|
|||
|
||||
def format DataOp(code, flagtype = logic) {{
|
||||
(regCcCode, immCcCode) = getCcCode(flagtype)
|
||||
regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs,
|
||||
shift, CondCodes<29:0>);
|
||||
regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs<7:0>,
|
||||
shift, CondCodes<29:>);
|
||||
op2 = op2;''' + code
|
||||
immCode = '''uint32_t op2 = shift_rm_imm(Rm, shift_size,
|
||||
shift, CondCodes<29:0>);
|
||||
shift, CondCodes<29:>);
|
||||
op2 = op2;''' + code
|
||||
regIop = InstObjParams(name, Name, 'PredIntOp',
|
||||
{"code": regCode,
|
||||
|
|
|
@ -58,6 +58,7 @@ def operands {{
|
|||
'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 3, maybePCRead, maybePCWrite),
|
||||
'Rn': ('IntReg', 'uw', 'RN', 'IsInteger', 4, maybePCRead, maybePCWrite),
|
||||
'R7': ('IntReg', 'uw', '7', 'IsInteger', 5),
|
||||
'R0': ('IntReg', 'uw', '0', 'IsInteger', 0),
|
||||
|
||||
#Destination register for load/store double instructions
|
||||
'Rdo': ('IntReg', 'uw', '(RD & ~1)', 'IsInteger', 4, maybePCRead, maybePCWrite),
|
||||
|
|
|
@ -52,6 +52,7 @@ namespace ArmISA
|
|||
Bitfield<23, 21> opcode23_21;
|
||||
Bitfield<22> opcode22;
|
||||
Bitfield<19> opcode19;
|
||||
Bitfield<18> opcode18;
|
||||
Bitfield<15, 12> opcode15_12;
|
||||
Bitfield<15> opcode15;
|
||||
Bitfield<7, 4> miscOpcode;
|
||||
|
|
Loading…
Reference in a new issue