ARM: Fix some bugs in the ISA desc and fill out some instructions.

This commit is contained in:
Gabe Black 2009-11-10 23:44:05 -08:00
parent 850eb54a7c
commit 5524af83ef
5 changed files with 98 additions and 41 deletions

View file

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

View file

@ -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)

View file

@ -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,

View file

@ -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),

View file

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