summaryrefslogtreecommitdiff
path: root/src/arch/arm/isa
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/arm/isa')
-rw-r--r--src/arch/arm/isa/bitfields.isa4
-rw-r--r--src/arch/arm/isa/decoder.isa362
-rw-r--r--src/arch/arm/isa/formats/branch.isa4
-rw-r--r--src/arch/arm/isa/formats/fp.isa4
-rw-r--r--src/arch/arm/isa/formats/macromem.isa126
-rw-r--r--src/arch/arm/isa/formats/pred.isa90
-rw-r--r--src/arch/arm/isa/formats/unimp.isa2
-rw-r--r--src/arch/arm/isa/formats/unknown.isa2
-rw-r--r--src/arch/arm/isa/formats/util.isa6
-rw-r--r--src/arch/arm/isa/operands.isa24
10 files changed, 389 insertions, 235 deletions
diff --git a/src/arch/arm/isa/bitfields.isa b/src/arch/arm/isa/bitfields.isa
index 5785939cc..8ff819983 100644
--- a/src/arch/arm/isa/bitfields.isa
+++ b/src/arch/arm/isa/bitfields.isa
@@ -38,14 +38,18 @@ def bitfield ENCODING encoding;
def bitfield OPCODE opcode;
def bitfield MEDIA_OPCODE mediaOpcode;
def bitfield MEDIA_OPCODE2 mediaOpcode2;
+def bitfield USEIMM useImm;
def bitfield OPCODE_24 opcode24;
def bitfield OPCODE_23_20 opcode23_20;
def bitfield OPCODE_23_21 opcode23_21;
def bitfield OPCODE_22 opcode22;
+def bitfield OPCODE_20 opcode20;
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;
+def bitfield OPC2 opc2;
def bitfield OPCODE_7 opcode7;
def bitfield OPCODE_4 opcode4;
diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa
index a999b52e9..ff20c6107 100644
--- a/src/arch/arm/isa/decoder.isa
+++ b/src/arch/arm/isa/decoder.isa
@@ -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();
@@ -91,9 +96,9 @@ format DataOp {
0x2: sub({{ Rd = resTemp = Rn - op2; }}, sub);
0x3: rsb({{ Rd = resTemp = op2 - Rn; }}, rsb);
0x4: add({{ Rd = resTemp = Rn + op2; }}, add);
- 0x5: adc({{ Rd = resTemp = Rn + op2 + Cpsr<29:>; }}, add);
- 0x6: sbc({{ Rd = resTemp = Rn - op2 - !Cpsr<29:>; }}, sub);
- 0x7: rsc({{ Rd = resTemp = op2 - Rn - !Cpsr<29:>; }}, rsb);
+ 0x5: adc({{ Rd = resTemp = Rn + op2 + CondCodes<29:>; }}, add);
+ 0x6: sbc({{ Rd = resTemp = Rn - op2 - !CondCodes<29:>; }}, sub);
+ 0x7: rsc({{ Rd = resTemp = op2 - Rn - !CondCodes<29:>; }}, rsb);
0x8: tst({{ resTemp = Rn & op2; }});
0x9: teq({{ resTemp = Rn ^ op2; }});
0xa: cmp({{ resTemp = Rn - op2; }}, sub);
@@ -105,10 +110,37 @@ format DataOp {
}
1: decode MISC_OPCODE {
0x0: decode OPCODE {
- 0x8: WarnUnimpl::mrs_cpsr();
- 0x9: WarnUnimpl::msr_cpsr();
- 0xa: WarnUnimpl::mrs_spsr();
- 0xb: WarnUnimpl::msr_spsr();
+ 0x8: PredOp::mrs_cpsr({{
+ Rd = (Cpsr | CondCodes) & 0xF8FF03DF;
+ }});
+ 0x9: decode USEIMM {
+ // The mask field is the same as the RN index.
+ 0: PredOp::msr_cpsr_reg({{
+ uint32_t newCpsr =
+ cpsrWriteByInstr(Cpsr | CondCodes,
+ Rm, RN, false);
+ Cpsr = ~CondCodesMask & newCpsr;
+ CondCodes = CondCodesMask & newCpsr;
+ }});
+ 1: PredImmOp::msr_cpsr_imm({{
+ uint32_t newCpsr =
+ cpsrWriteByInstr(Cpsr | CondCodes,
+ rotated_imm, RN, false);
+ Cpsr = ~CondCodesMask & newCpsr;
+ CondCodes = CondCodesMask & newCpsr;
+ }});
+ }
+ 0xa: PredOp::mrs_spsr({{ Rd = Spsr; }});
+ 0xb: decode USEIMM {
+ // The mask field is the same as the RN index.
+ 0: PredOp::msr_spsr_reg({{
+ Spsr = spsrWriteByInstr(Spsr, Rm, RN, false);
+ }});
+ 1: PredImmOp::msr_spsr_imm({{
+ Spsr = spsrWriteByInstr(Spsr, rotated_imm,
+ RN, false);
+ }});
+ }
}
0x1: decode OPCODE {
0x9: BranchExchange::bx({{ }});
@@ -129,28 +161,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);
}
}
}
@@ -163,9 +199,15 @@ format DataOp {
0x2: subi({{ Rd = resTemp = Rn - rotated_imm; }}, sub);
0x3: rsbi({{ Rd = resTemp = rotated_imm - Rn; }}, rsb);
0x4: addi({{ Rd = resTemp = Rn + rotated_imm; }}, add);
- 0x5: adci({{ Rd = resTemp = Rn + rotated_imm + Cpsr<29:>; }}, add);
- 0x6: sbci({{ Rd = resTemp = Rn -rotated_imm - !Cpsr<29:>; }}, sub);
- 0x7: rsci({{ Rd = resTemp = rotated_imm - Rn - !Cpsr<29:>;}}, rsb);
+ 0x5: adci({{
+ Rd = resTemp = Rn + rotated_imm + CondCodes<29:>;
+ }}, add);
+ 0x6: sbci({{
+ Rd = resTemp = Rn -rotated_imm - !CondCodes<29:>;
+ }}, sub);
+ 0x7: rsci({{
+ Rd = resTemp = rotated_imm - Rn - !CondCodes<29:>;
+ }}, rsb);
0x8: tsti({{ resTemp = Rn & rotated_imm; }});
0x9: teqi({{ resTemp = Rn ^ rotated_imm; }});
0xa: cmpi({{ resTemp = Rn - rotated_imm; }}, sub);
@@ -178,11 +220,27 @@ format DataOp {
}
1: decode OPCODE {
// The following two instructions aren't supposed to be defined
- 0x8: WarnUnimpl::undefined_instruction();
- 0x9: WarnUnimpl::undefined_instruction();
-
- 0xa: WarnUnimpl::mrs_i_cpsr();
- 0xb: WarnUnimpl::mrs_i_spsr();
+ 0x8: DataOp::movw({{ Rd = IMMED_11_0 | (RN << 12) ; }});
+ 0x9: decode RN {
+ 0: decode IMM {
+ 0: PredImmOp::nop({{ ; }});
+ 1: WarnUnimpl::yield();
+ 2: WarnUnimpl::wfe();
+ 3: WarnUnimpl::wfi();
+ 4: WarnUnimpl::sev();
+ }
+ default: PredImmOp::msr_i_cpsr({{
+ uint32_t newCpsr =
+ cpsrWriteByInstr(Cpsr | CondCodes,
+ rotated_imm, RN, false);
+ Cpsr = ~CondCodesMask & newCpsr;
+ CondCodes = CondCodesMask & newCpsr;
+ }});
+ }
+ 0xa: PredOp::movt({{ Rd = IMMED_11_0 << 16 | RN << 28 | Rd<15:0>; }});
+ 0xb: PredImmOp::msr_i_spsr({{
+ Spsr = spsrWriteByInstr(Spsr, rotated_imm, RN, false);
+ }});
}
}
0x2: AddrMode2::addrMode2(Disp, disp);
@@ -324,77 +382,79 @@ format DataOp {
}
}
0x7: decode OPCODE_24 {
- 0: decode CPNUM {
- // Coprocessor Instructions
- 0x1: decode OPCODE_4 {
+ 0: decode OPCODE_4 {
+ 0: decode CPNUM {
format FloatOp {
- // Basic FPA Instructions
- 0: decode OPCODE_23_20 {
- 0x0: decode OPCODE_15 {
- 0: adf({{ Fd.sf = Fn.sf + Fm.sf; }});
- 1: mvf({{ Fd.sf = Fm.sf; }});
- }
- 0x1: decode OPCODE_15 {
- 0: muf({{ Fd.sf = Fn.sf * Fm.sf; }});
- 1: mnf({{ Fd.sf = -Fm.sf; }});
- }
- 0x2: decode OPCODE_15 {
- 0: suf({{ Fd.sf = Fn.sf - Fm.sf; }});
- 1: abs({{ Fd.sf = fabs(Fm.sf); }});
- }
- 0x3: decode OPCODE_15 {
- 0: rsf({{ Fd.sf = Fm.sf - Fn.sf; }});
- 1: rnd({{ Fd.sf = rint(Fm.sf); }});
- }
- 0x4: decode OPCODE_15 {
- 0: dvf({{ Fd.sf = Fn.sf / Fm.sf; }});
- 1: sqt({{ Fd.sf = sqrt(Fm.sf); }});
- }
- 0x5: decode OPCODE_15 {
- 0: rdf({{ Fd.sf = Fm.sf / Fn.sf; }});
- 1: log({{ Fd.sf = log10(Fm.sf); }});
- }
- 0x6: decode OPCODE_15 {
- 0: pow({{ Fd.sf = pow(Fm.sf, Fn.sf); }});
- 1: lgn({{ Fd.sf = log(Fm.sf); }});
- }
- 0x7: decode OPCODE_15 {
- 0: rpw({{ Fd.sf = pow(Fn.sf, Fm.sf); }});
- 1: exp({{ Fd.sf = exp(Fm.sf); }});
- }
- 0x8: decode OPCODE_15 {
- 0: rmf({{ Fd.sf = drem(Fn.sf, Fm.sf); }});
- 1: sin({{ Fd.sf = sin(Fm.sf); }});
- }
- 0x9: decode OPCODE_15 {
- 0: fml({{ Fd.sf = Fn.sf * Fm.sf; }});
- 1: cos({{ Fd.sf = cos(Fm.sf); }});
- }
- 0xa: decode OPCODE_15 {
- 0: fdv({{ Fd.sf = Fn.sf / Fm.sf; }});
- 1: tan({{ Fd.sf = tan(Fm.sf); }});
- }
- 0xb: decode OPCODE_15 {
- 0: frd({{ Fd.sf = Fm.sf / Fn.sf; }});
- 1: asn({{ Fd.sf = asin(Fm.sf); }});
- }
- 0xc: decode OPCODE_15 {
- 0: pol({{ Fd.sf = atan2(Fn.sf, Fm.sf); }});
- 1: acs({{ Fd.sf = acos(Fm.sf); }});
- }
- 0xd: decode OPCODE_15 {
- 1: atn({{ Fd.sf = atan(Fm.sf); }});
- }
- 0xe: decode OPCODE_15 {
- // Unnormalised Round
- 1: FailUnimpl::urd();
- }
- 0xf: decode OPCODE_15 {
- // Normalise
- 1: FailUnimpl::nrm();
- }
- }
- 1: decode OPCODE_15_12 {
+ 0x1: decode OPCODE_23_20 {
+ 0x0: decode OPCODE_15 {
+ 0: adf({{ Fd.sf = Fn.sf + Fm.sf; }});
+ 1: mvf({{ Fd.sf = Fm.sf; }});
+ }
+ 0x1: decode OPCODE_15 {
+ 0: muf({{ Fd.sf = Fn.sf * Fm.sf; }});
+ 1: mnf({{ Fd.sf = -Fm.sf; }});
+ }
+ 0x2: decode OPCODE_15 {
+ 0: suf({{ Fd.sf = Fn.sf - Fm.sf; }});
+ 1: abs({{ Fd.sf = fabs(Fm.sf); }});
+ }
+ 0x3: decode OPCODE_15 {
+ 0: rsf({{ Fd.sf = Fm.sf - Fn.sf; }});
+ 1: rnd({{ Fd.sf = rint(Fm.sf); }});
+ }
+ 0x4: decode OPCODE_15 {
+ 0: dvf({{ Fd.sf = Fn.sf / Fm.sf; }});
+ 1: sqt({{ Fd.sf = sqrt(Fm.sf); }});
+ }
+ 0x5: decode OPCODE_15 {
+ 0: rdf({{ Fd.sf = Fm.sf / Fn.sf; }});
+ 1: log({{ Fd.sf = log10(Fm.sf); }});
+ }
+ 0x6: decode OPCODE_15 {
+ 0: pow({{ Fd.sf = pow(Fm.sf, Fn.sf); }});
+ 1: lgn({{ Fd.sf = log(Fm.sf); }});
+ }
+ 0x7: decode OPCODE_15 {
+ 0: rpw({{ Fd.sf = pow(Fn.sf, Fm.sf); }});
+ 1: exp({{ Fd.sf = exp(Fm.sf); }});
+ }
+ 0x8: decode OPCODE_15 {
+ 0: rmf({{ Fd.sf = drem(Fn.sf, Fm.sf); }});
+ 1: sin({{ Fd.sf = sin(Fm.sf); }});
+ }
+ 0x9: decode OPCODE_15 {
+ 0: fml({{ Fd.sf = Fn.sf * Fm.sf; }});
+ 1: cos({{ Fd.sf = cos(Fm.sf); }});
+ }
+ 0xa: decode OPCODE_15 {
+ 0: fdv({{ Fd.sf = Fn.sf / Fm.sf; }});
+ 1: tan({{ Fd.sf = tan(Fm.sf); }});
+ }
+ 0xb: decode OPCODE_15 {
+ 0: frd({{ Fd.sf = Fm.sf / Fn.sf; }});
+ 1: asn({{ Fd.sf = asin(Fm.sf); }});
+ }
+ 0xc: decode OPCODE_15 {
+ 0: pol({{ Fd.sf = atan2(Fn.sf, Fm.sf); }});
+ 1: acs({{ Fd.sf = acos(Fm.sf); }});
+ }
+ 0xd: decode OPCODE_15 {
+ 1: atn({{ Fd.sf = atan(Fm.sf); }});
+ }
+ 0xe: decode OPCODE_15 {
+ // Unnormalised Round
+ 1: FailUnimpl::urd();
+ }
+ 0xf: decode OPCODE_15 {
+ // Normalise
+ 1: FailUnimpl::nrm();
+ }
+ } // OPCODE_23_20
+ } // format FloatOp
+ } // CPNUM
+ 1: decode CPNUM { // 27-24=1110,4 ==1
+ 1: decode OPCODE_15_12 {
+ format FloatOp {
0xf: decode OPCODE_23_21 {
format FloatCmp {
0x4: cmf({{ Fn.df }}, {{ Fm.df }});
@@ -417,36 +477,86 @@ format DataOp {
0x4: FailUnimpl::wfc();
0x5: FailUnimpl::rfc();
}
- }
+ } // format FloatOp
}
- }
- 0xa: decode MISC_OPCODE {
- 0x1: decode MEDIA_OPCODE {
- 0xf: decode RN {
- 0x0: FloatOp::fmrx_fpsid({{ Rd = Fpsid; }});
- 0x1: FloatOp::fmrx_fpscr({{ Rd = Fpscr; }});
- 0x8: FloatOp::fmrx_fpexc({{ Rd = Fpexc; }});
- }
- 0xe: decode RN {
- 0x0: FloatOp::fmxr_fpsid({{ Fpsid = Rd; }});
- 0x1: FloatOp::fmxr_fpscr({{ Fpscr = Rd; }});
- 0x8: FloatOp::fmxr_fpexc({{ Fpexc = Rd; }});
+ 0xa: decode MISC_OPCODE {
+ 0x1: decode MEDIA_OPCODE {
+ 0xf: decode RN {
+ 0x0: FloatOp::fmrx_fpsid({{ Rd = Fpsid; }});
+ 0x1: FloatOp::fmrx_fpscr({{ Rd = Fpscr; }});
+ 0x8: FloatOp::fmrx_fpexc({{ Rd = Fpexc; }});
+ }
+ 0xe: decode RN {
+ 0x0: FloatOp::fmxr_fpsid({{ Fpsid = Rd; }});
+ 0x1: FloatOp::fmxr_fpscr({{ Fpscr = Rd; }});
+ 0x8: FloatOp::fmxr_fpexc({{ Fpexc = Rd; }});
+ }
+ } // MEDIA_OPCODE (MISC_OPCODE 0x1)
+ } // MISC_OPCODE (CPNUM 0xA)
+ 0xf: decode RN {
+ // Barrriers, Cache Maintence, NOPS
+ 7: decode OPCODE_23_21 {
+ 0: decode RM {
+ 0: decode OPC2 {
+ 4: decode OPCODE_20 {
+ 0: PredOp::mcr_cp15_nop1({{ }}); // was wfi
+ }
+ }
+ 1: WarnUnimpl::cp15_cache_maint();
+ 4: WarnUnimpl::cp15_par();
+ 5: decode OPC2 {
+ 0,1: WarnUnimpl::cp15_cache_maint2();
+ 4: PredOp::cp15_isb({{ ; }}, IsMemBarrier, IsSerializeBefore);
+ 6,7: WarnUnimpl::cp15_bp_maint();
+ }
+ 6: WarnUnimpl::cp15_cache_maint3();
+ 8: WarnUnimpl::cp15_va_to_pa();
+ 10: decode OPC2 {
+ 1,2: WarnUnimpl::cp15_cache_maint3();
+ 4: PredOp::cp15_dsb({{ ; }}, IsMemBarrier, IsSerializeBefore);
+ 5: PredOp::cp15_dmb({{ ; }}, IsMemBarrier, IsSerializeBefore);
+ }
+ 11: WarnUnimpl::cp15_cache_maint4();
+ 13: decode OPC2 {
+ 1: decode OPCODE_20 {
+ 0: PredOp::mcr_cp15_nop2({{ }}); // was prefetch
+ }
+ }
+ 14: WarnUnimpl::cp15_cache_maint5();
+ } // RM
+ } // OPCODE_23_21 CR
+
+ // Thread ID and context ID registers
+ // Thread ID register needs cheaper access than miscreg
+ 13: WarnUnimpl::mcr_mrc_cp15_c7();
+
+ // All the rest
+ default: decode OPCODE_20 {
+ 0: PredOp::mcr_cp15({{
+ fault = setCp15Register(Rd, RN, OPCODE_23_21, RM, OPC2);
+ }});
+ 1: PredOp::mrc_cp15({{
+ fault = readCp15Register(Rd, RN, OPCODE_23_21, RM, OPC2);
+ }});
}
- }
+ } // RN
+ } // CPNUM (OP4 == 1)
+ } //OPCODE_4
+
+#if FULL_SYSTEM
+ 1: PredOp::swi({{ fault = new SupervisorCall; }}, IsSerializeAfter, IsNonSpeculative, IsSyscall);
+#else
+ 1: PredOp::swi({{ if (testPredicate(CondCodes, condCode))
+ {
+ if (IMMED_23_0)
+ xc->syscall(IMMED_23_0);
+ else
+ xc->syscall(R7);
}
- }
- format PredOp {
- // ARM System Call (SoftWare Interrupt)
- 1: swi({{ if (testPredicate(Cpsr, condCode))
- {
- if (IMMED_23_0)
- xc->syscall(IMMED_23_0);
- else
- xc->syscall(R7);
- }
- }});
- }
- }
+ }});
+#endif // FULL_SYSTEM
+ } // OPCODE_24
+
}
}
diff --git a/src/arch/arm/isa/formats/branch.isa b/src/arch/arm/isa/formats/branch.isa
index 95f4f14e1..5f1b541ff 100644
--- a/src/arch/arm/isa/formats/branch.isa
+++ b/src/arch/arm/isa/formats/branch.isa
@@ -52,7 +52,7 @@ def format Branch(code,*opt_flags) {{
else:
inst_flags += ('IsCondControl', )
- icode = 'if (testPredicate(Cpsr, condCode)) {\n'
+ icode = 'if (testPredicate(CondCodes, condCode)) {\n'
icode += code
icode += ' NPC = NPC + 4 + disp;\n'
icode += '} else {\n'
@@ -90,7 +90,7 @@ def format BranchExchange(code,*opt_flags) {{
#Condition code
- icode = 'if (testPredicate(Cpsr, condCode)) {\n'
+ icode = 'if (testPredicate(CondCodes, condCode)) {\n'
icode += code
icode += ' NPC = Rm & 0xfffffffe; // Masks off bottom bit\n'
icode += '} else {\n'
diff --git a/src/arch/arm/isa/formats/fp.isa b/src/arch/arm/isa/formats/fp.isa
index e88531580..e79529615 100644
--- a/src/arch/arm/isa/formats/fp.isa
+++ b/src/arch/arm/isa/formats/fp.isa
@@ -119,8 +119,8 @@ let {{
_ic = %(fReg1)s >= %(fReg2)s;
_iv = (isnan(%(fReg1)s) || isnan(%(fReg2)s)) & 1;
- Cpsr = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
- (Cpsr & 0x0FFFFFFF);
+ CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
+ (CondCodes & 0x0FFFFFFF);
'''
}};
diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa
index 355a67ea9..c834c22cb 100644
--- a/src/arch/arm/isa/formats/macromem.isa
+++ b/src/arch/arm/isa/formats/macromem.isa
@@ -72,6 +72,18 @@ let {{
'predicate_test': predicateTest},
['IsMicroop'])
+ microLdrRetUopCode = '''
+ Ra = Mem;
+ Cpsr = cpsrWriteByInstr(Cpsr, Spsr, 0xF, true);
+ '''
+ microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop',
+ 'MicroMemOp',
+ {'memacc_code': microLdrRetUopCode,
+ 'ea_code':
+ 'EA = Rb + (UP ? imm : -imm);',
+ 'predicate_test': predicateTest},
+ ['IsMicroop'])
+
microStrUopIop = InstObjParams('str_uop', 'MicroStrUop',
'MicroMemOp',
{'memacc_code': 'Mem = Ra;',
@@ -80,14 +92,19 @@ let {{
['IsMicroop'])
header_output = MicroMemDeclare.subst(microLdrUopIop) + \
+ MicroMemDeclare.subst(microLdrRetUopIop) + \
MicroMemDeclare.subst(microStrUopIop)
decoder_output = MicroConstructor.subst(microLdrUopIop) + \
+ MicroConstructor.subst(microLdrRetUopIop) + \
MicroConstructor.subst(microStrUopIop)
exec_output = LoadExecute.subst(microLdrUopIop) + \
+ LoadExecute.subst(microLdrRetUopIop) + \
StoreExecute.subst(microStrUopIop) + \
LoadInitiateAcc.subst(microLdrUopIop) + \
+ LoadInitiateAcc.subst(microLdrRetUopIop) + \
StoreInitiateAcc.subst(microStrUopIop) + \
LoadCompleteAcc.subst(microLdrUopIop) + \
+ LoadCompleteAcc.subst(microLdrRetUopIop) + \
StoreCompleteAcc.subst(microStrUopIop)
}};
@@ -178,73 +195,64 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
{
%(constructor)s;
- uint32_t regs_to_handle = reglist;
- uint32_t start_addr = 0;
+ uint32_t regs = reglist;
+ uint32_t addr = 0;
+ bool up = machInst.puswl.up;
- switch (puswl)
- {
- case 0x00: // stmda
- case 0x01: // L ldmda_l
- case 0x02: // W stmda_w
- case 0x03: // WL ldmda_wl
- start_addr = (ones << 2) - 4;
- break;
- case 0x08: // U stmia_u
- case 0x09: // U L ldmia_ul
- case 0x0a: // U W stmia
- case 0x0b: // U WL ldmia
- start_addr = 0;
- break;
- case 0x10: // P stmdb
- case 0x11: // P L ldmdb
- case 0x12: // P W stmdb
- case 0x13: // P WL ldmdb
- start_addr = (ones << 2); // U-bit is already 0 for subtract
- break;
- case 0x18: // PU stmib
- case 0x19: // PU L ldmib
- case 0x1a: // PU W stmib
- case 0x1b: // PU WL ldmib
- start_addr = 4;
- break;
- default:
- panic("Unhandled Load/Store Multiple Instruction, "
- "puswl = 0x%x", (unsigned) puswl);
- break;
- }
+ if (!up)
+ addr = (ones << 2) - 4;
+
+ if (machInst.puswl.prepost)
+ addr += 4;
- // Add 0 to Rn and stick it in Raddr (register 17).
+ // Add 0 to Rn and stick it in ureg0.
// This is equivalent to a move.
- microOps[0] = new MicroAddiUop(machInst, 17, RN, 0);
+ microOps[0] = new MicroAddiUop(machInst, INTREG_UREG0, RN, 0);
- unsigned j = 0;
- for (int i = 1; i < ones+1; i++) {
- // Get next available bit for transfer
- while (! ( regs_to_handle & (1<<j)))
- j++;
- regs_to_handle &= ~(1<<j);
+ unsigned reg = 0;
+ bool force_user = machInst.puswl.psruser & !OPCODE_15;
+ bool exception_ret = machInst.puswl.psruser & OPCODE_15;
- if (loadop)
- microOps[i] = new MicroLdrUop(machInst, j, 17, start_addr);
- else
- microOps[i] = new MicroStrUop(machInst, j, 17, start_addr);
+ for (int i = 1; i < ones + 1; i++) {
+ // Find the next register.
+ while (!bits(regs, reg))
+ reg++;
+ replaceBits(regs, reg, 0);
+
+ unsigned regIdx = reg;
+ if (force_user) {
+ regIdx = intRegForceUser(regIdx);
+ }
+
+ if (machInst.puswl.loadOp) {
+ if (reg == INTREG_PC && exception_ret) {
+ // This must be the exception return form of ldm.
+ microOps[i] =
+ new MicroLdrRetUop(machInst, regIdx, INTREG_UREG0, addr);
+ } else {
+ microOps[i] =
+ new MicroLdrUop(machInst, regIdx, INTREG_UREG0, addr);
+ }
+ } else {
+ microOps[i] =
+ new MicroStrUop(machInst, regIdx, INTREG_UREG0, addr);
+ }
if (up)
- start_addr += 4;
+ addr += 4;
else
- start_addr -= 4;
+ addr -= 4;
}
- if (writeback) {
+ StaticInstPtr &lastUop = microOps[numMicroops - 1];
+ if (machInst.puswl.writeback) {
if (up) {
- microOps[numMicroops-1] =
- new MicroAddiUop(machInst, RN, RN, ones * 4);
+ lastUop = new MicroAddiUop(machInst, RN, RN, ones * 4);
} else {
- microOps[numMicroops-1] =
- new MicroSubiUop(machInst, RN, RN, ones * 4);
+ lastUop = new MicroSubiUop(machInst, RN, RN, ones * 4);
}
}
- microOps[numMicroops-1]->setLastMicroop();
+ lastUop->setLastMicroop();
}
}};
@@ -285,14 +293,14 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
if (writeback)
{
if (up) {
- microOps[numMicroops-1] =
+ microOps[numMicroops - 1] =
new MicroAddiUop(machInst, RN, RN, disp8);
} else {
- microOps[numMicroops-1] =
+ microOps[numMicroops - 1] =
new MicroSubiUop(machInst, RN, RN, disp8);
}
}
- microOps[numMicroops-1]->setLastMicroop();
+ microOps[numMicroops - 1]->setLastMicroop();
}
}};
@@ -316,14 +324,14 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
if (writeback) {
if (up) {
- microOps[numMicroops-1] =
+ microOps[numMicroops - 1] =
new MicroAddiUop(machInst, RN, RN, disp8);
} else {
- microOps[numMicroops-1] =
+ microOps[numMicroops - 1] =
new MicroSubiUop(machInst, RN, RN, disp8);
}
}
- microOps[numMicroops-1]->setLastMicroop();
+ microOps[numMicroops - 1]->setLastMicroop();
}
}};
diff --git a/src/arch/arm/isa/formats/pred.isa b/src/arch/arm/isa/formats/pred.isa
index e90788c91..0d6ee32f7 100644
--- a/src/arch/arm/isa/formats/pred.isa
+++ b/src/arch/arm/isa/formats/pred.isa
@@ -34,7 +34,7 @@
//
let {{
- predicateTest = 'testPredicate(Cpsr, condCode)'
+ predicateTest = 'testPredicate(CondCodes, condCode)'
}};
def template PredOpExecute {{
@@ -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;
-
- Cpsr = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
- (Cpsr & 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 = 'Cpsr<29:>'
- iv = 'Cpsr<28:>'
+ 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, 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})
+ 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,
+ "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 = 'Cpsr<29:>'
- ivValue = 'Cpsr<28:>'
+ 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)'
@@ -138,18 +166,18 @@ let {{
icValue = 'findCarry(32, resTemp, rotated_imm, ~Rn)'
ivValue = 'findOverflow(32, resTemp, rotated_imm, ~Rn)'
else:
- icValue = '(rotate ? rotated_carry:Cpsr<29:>)'
- ivValue = 'Cpsr<28:>'
+ icValue = '(rotate ? rotated_carry:CondCodes<29:>)'
+ ivValue = 'CondCodes<28:>'
return calcCcCode % vars()
}};
def format DataOp(code, flagtype = logic) {{
(regCcCode, immCcCode) = getCcCode(flagtype)
- regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs,
- shift, Cpsr<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, Cpsr<29:0>);
+ shift, CondCodes<29:>);
op2 = op2;''' + code
regIop = InstObjParams(name, Name, 'PredIntOp',
{"code": regCode,
diff --git a/src/arch/arm/isa/formats/unimp.isa b/src/arch/arm/isa/formats/unimp.isa
index c82bb41c6..6909c3f85 100644
--- a/src/arch/arm/isa/formats/unimp.isa
+++ b/src/arch/arm/isa/formats/unimp.isa
@@ -115,7 +115,7 @@ output exec {{
panic("attempt to execute unimplemented instruction '%s' "
"(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
inst2string(machInst));
- return new UnimplementedOpcodeFault;
+ return new UnimpFault("Unimplemented Instruction");
}
Fault
diff --git a/src/arch/arm/isa/formats/unknown.isa b/src/arch/arm/isa/formats/unknown.isa
index 2ad7a2506..97a0caa6b 100644
--- a/src/arch/arm/isa/formats/unknown.isa
+++ b/src/arch/arm/isa/formats/unknown.isa
@@ -74,7 +74,7 @@ output exec {{
{
panic("attempt to execute unknown instruction "
"(inst 0x%08x, opcode 0x%x, binary: %s)", machInst, OPCODE, inst2string(machInst));
- return new UnimplementedOpcodeFault;
+ return new UnimpFault("Unimplemented Instruction");
}
}};
diff --git a/src/arch/arm/isa/formats/util.isa b/src/arch/arm/isa/formats/util.isa
index b5efec568..d42ffb147 100644
--- a/src/arch/arm/isa/formats/util.isa
+++ b/src/arch/arm/isa/formats/util.isa
@@ -33,8 +33,10 @@ let {{
# Generic substitutions for Arm instructions
def ArmGenericCodeSubs(code):
# Substitute in the shifted portion of operations
- new_code = re.sub(r'Rm_Imm', 'shift_rm_imm(Rm, shift_size, shift, Cpsr<29:>)', code)
- new_code = re.sub(r'Rm_Rs', 'shift_rm_rs(Rm, Rs, shift, Cpsr<29:>)', new_code)
+ new_code = re.sub(r'Rm_Imm',
+ 'shift_rm_imm(Rm, shift_size, shift, CondCodes<29:>)', code)
+ new_code = re.sub(r'Rm_Rs',
+ 'shift_rm_rs(Rm, Rs, shift, CondCodes<29:>)', new_code)
return new_code
def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa
index ac7427dad..aadefc79c 100644
--- a/src/arch/arm/isa/operands.isa
+++ b/src/arch/arm/isa/operands.isa
@@ -58,15 +58,16 @@ 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),
'Rde': ('IntReg', 'uw', '(RD | 1)', 'IsInteger', 5, maybePCRead, maybePCWrite),
- 'Raddr': ('IntReg', 'uw', '17', 'IsInteger', 6),
- 'Rhi': ('IntReg', 'uw', '18', 'IsInteger', 7),
- 'Rlo': ('IntReg', 'uw', '19', 'IsInteger', 8),
- 'LR': ('IntReg', 'uw', '14', 'IsInteger', 9),
+ 'Rhi': ('IntReg', 'uw', 'INTREG_RHI', 'IsInteger', 7),
+ 'Rlo': ('IntReg', 'uw', 'INTREG_RLO', 'IsInteger', 8),
+ 'LR': ('IntReg', 'uw', 'INTREG_LR', 'IsInteger', 9),
+ 'CondCodes': ('IntReg', 'uw', 'INTREG_CONDCODES', 'IsInteger', 10),
#Register fields for microops
'Ra' : ('IntReg', 'uw', 'ura', 'IsInteger', 11, maybePCRead, maybePCWrite),
@@ -80,12 +81,13 @@ def operands {{
#Memory Operand
'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 30),
- 'Cpsr': ('ControlReg', 'uw', 'MISCREG_CPSR', 'IsInteger', 40),
- 'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', 'IsInteger', 41),
- 'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', 'IsInteger', 42),
- 'Fpscr': ('ControlReg', 'uw', 'MISCREG_FPSCR', 'IsInteger', 43),
- 'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', 'IsInteger', 44),
- 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 45),
- 'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 46)
+ 'Cpsr': ('ControlReg', 'uw', 'MISCREG_CPSR', (None, None, 'IsControl'), 40),
+ 'Spsr': ('ControlReg', 'uw', 'MISCREG_SPSR', (None, None, 'IsControl'), 41),
+ 'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', (None, None, 'IsControl'), 42),
+ 'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', (None, None, 'IsControl'), 43),
+ 'Fpscr': ('ControlReg', 'uw', 'MISCREG_FPSCR', (None, None, 'IsControl'), 44),
+ 'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', (None, None, 'IsControl'), 45),
+ 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 50),
+ 'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 51)
}};