summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/arm/insts/macromem.hh16
-rw-r--r--src/arch/arm/isa/decoder.isa22
-rw-r--r--src/arch/arm/isa/formats/macromem.isa80
-rw-r--r--src/arch/arm/isa/formats/util.isa64
4 files changed, 95 insertions, 87 deletions
diff --git a/src/arch/arm/insts/macromem.hh b/src/arch/arm/insts/macromem.hh
index c215cdeab..541c9e3f5 100644
--- a/src/arch/arm/insts/macromem.hh
+++ b/src/arch/arm/insts/macromem.hh
@@ -64,6 +64,22 @@ class MicroIntOp : public PredOp
};
/**
+ * Memory microops which use IntReg + Imm addressing
+ */
+class MicroMemOp : public MicroIntOp
+{
+ protected:
+ unsigned memAccessFlags;
+
+ MicroMemOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
+ RegIndex _ura, RegIndex _urb, uint8_t _imm)
+ : MicroIntOp(mnem, machInst, __opClass, _ura, _urb, _imm),
+ memAccessFlags(0)
+ {
+ }
+};
+
+/**
* Arm Macro Memory operations like LDM/STM
*/
class ArmMacroMemoryOp : public PredMacroOp
diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa
index fbeb2da22..f52cbe1a1 100644
--- a/src/arch/arm/isa/decoder.isa
+++ b/src/arch/arm/isa/decoder.isa
@@ -39,33 +39,13 @@
//
decode COND_CODE default Unknown::unknown() {
0xf: decode COND_CODE {
- 0x0: decode OPCODE {
- // Just a simple trick to allow us to specify our new uops here
- 0x2: ArmLoadMemory::ldr_uop({{ Rd = Mem; }},
- {{ EA = Raddr + (up ? disp : -disp); }},
- inst_flags = [IsMicroop]);
- 0x3: ArmStoreMemory::str_uop({{ Mem = Rd; }},
- {{ EA = Raddr + (up ? disp : -disp); }},
- inst_flags = [IsMicroop]);
- }
0x1: decode OPCODE {
+ // Just a simple trick to allow us to specify our new uops here
0x0: PredIntOp::mvtd_uop({{ Fd.ud = ((uint64_t) Rhi << 32)|Rlo; }},
'IsMicroop');
0x1: PredIntOp::mvfd_uop({{ Rhi = (Fd.ud >> 32) & 0xffffffff;
Rlo = Fd.ud & 0xffffffff; }},
'IsMicroop');
- 0x2: ArmLoadMemory::ldhi_uop({{ Rhi = Mem; }},
- {{ EA = Rn + (up ? disp : -disp); }},
- inst_flags = [IsMicroop]);
- 0x3: ArmLoadMemory::ldlo_uop({{ Rlo = Mem; }},
- {{ EA = Rn + (up ? disp : -disp); }},
- inst_flags = [IsMicroop]);
- 0x4: ArmStoreMemory::sthi_uop({{ Mem = Rhi; }},
- {{ EA = Rn + (up ? disp : -disp); }},
- inst_flags = [IsMicroop]);
- 0x5: ArmStoreMemory::stlo_uop({{ Mem = Rlo; }},
- {{ EA = Rn + (up ? disp : -disp); }},
- inst_flags = [IsMicroop]);
}
default: Unknown::unknown(); // TODO: Ignore other NV space for now
}
diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa
index 9b3a4f75f..be9504051 100644
--- a/src/arch/arm/isa/formats/macromem.isa
+++ b/src/arch/arm/isa/formats/macromem.isa
@@ -29,13 +29,29 @@
// Authors: Stephen Hines
// Gabe Black
+////////////////////////////////////////////////////////////////////
+//
+// Common microop templates
+//
+
+def template MicroConstructor {{
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
+ RegIndex _ura,
+ RegIndex _urb,
+ uint8_t _imm)
+ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+ _ura, _urb, _imm)
+ {
+ %(constructor)s;
+ }
+}};
////////////////////////////////////////////////////////////////////
//
-// Integer = Integer op Immediate microops
+// Load/store microops
//
-def template MicroIntDeclare {{
+def template MicroMemDeclare {{
class %(class_name)s : public %(base_class)s
{
public:
@@ -43,19 +59,52 @@ def template MicroIntDeclare {{
RegIndex _ura, RegIndex _urb,
uint8_t _imm);
%(BasicExecDeclare)s
+ %(InitiateAccDeclare)s
+ %(CompleteAccDeclare)s
};
}};
-def template MicroIntConstructor {{
- inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
- RegIndex _ura,
- RegIndex _urb,
- uint8_t _imm)
- : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
- _ura, _urb, _imm)
+let {{
+ microLdrUopIop = InstObjParams('ldr_uop', 'MicroLdrUop',
+ 'MicroMemOp',
+ {'memacc_code': 'Ra = Mem;',
+ 'ea_code': 'EA = Rb + (UP ? imm : -imm);',
+ 'predicate_test': predicateTest},
+ ['IsMicroop'])
+
+ microStrUopIop = InstObjParams('str_uop', 'MicroStrUop',
+ 'MicroMemOp',
+ {'memacc_code': 'Mem = Ra;',
+ 'ea_code': 'EA = Rb + (UP ? imm : -imm);',
+ 'predicate_test': predicateTest},
+ ['IsMicroop'])
+
+ header_output = MicroMemDeclare.subst(microLdrUopIop) + \
+ MicroMemDeclare.subst(microStrUopIop)
+ decoder_output = MicroConstructor.subst(microLdrUopIop) + \
+ MicroConstructor.subst(microStrUopIop)
+ exec_output = LoadExecute.subst(microLdrUopIop) + \
+ StoreExecute.subst(microStrUopIop) + \
+ LoadInitiateAcc.subst(microLdrUopIop) + \
+ StoreInitiateAcc.subst(microStrUopIop) + \
+ LoadCompleteAcc.subst(microLdrUopIop) + \
+ StoreCompleteAcc.subst(microStrUopIop)
+}};
+
+////////////////////////////////////////////////////////////////////
+//
+// Integer = Integer op Immediate microops
+//
+
+def template MicroIntDeclare {{
+ class %(class_name)s : public %(base_class)s
{
- %(constructor)s;
- }
+ public:
+ %(class_name)s(ExtMachInst machInst,
+ RegIndex _ura, RegIndex _urb,
+ uint8_t _imm);
+ %(BasicExecDeclare)s
+ };
}};
let {{
@@ -73,8 +122,8 @@ let {{
header_output = MicroIntDeclare.subst(microAddiUopIop) + \
MicroIntDeclare.subst(microSubiUopIop)
- decoder_output = MicroIntConstructor.subst(microAddiUopIop) + \
- MicroIntConstructor.subst(microSubiUopIop)
+ decoder_output = MicroConstructor.subst(microAddiUopIop) + \
+ MicroConstructor.subst(microSubiUopIop)
exec_output = PredOpExecute.subst(microAddiUopIop) + \
PredOpExecute.subst(microSubiUopIop)
}};
@@ -148,7 +197,10 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
j++;
regs_to_handle &= ~(1<<j);
- microOps[i] = gen_ldrstr_uop(machInst, loadop, j, start_addr);
+ if (loadop)
+ microOps[i] = new MicroLdrUop(machInst, j, 17, start_addr);
+ else
+ microOps[i] = new MicroStrUop(machInst, j, 17, start_addr);
if (up)
start_addr += 4;
diff --git a/src/arch/arm/isa/formats/util.isa b/src/arch/arm/isa/formats/util.isa
index e9cb533d6..ea4ffa660 100644
--- a/src/arch/arm/isa/formats/util.isa
+++ b/src/arch/arm/isa/formats/util.isa
@@ -101,67 +101,27 @@ output decoder {{
return str;
}
- // Generate the bit pattern for an Ldr_uop or Str_uop;
- StaticInstPtr
- gen_ldrstr_uop(uint32_t baseinst, int loadop, uint32_t rd, int32_t disp)
- {
- StaticInstPtr newInst;
- uint32_t newMachInst = baseinst & 0xffff0000;
- newMachInst |= (rd << 12);
- newMachInst |= disp;
- if (loadop)
- newInst = new Ldr_uop(newMachInst);
- else
- newInst = new Str_uop(newMachInst);
- return newInst;
- }
-
// Emits uops for a double fp move
- int
- emit_ldfstf_uops(StaticInstPtr* microOps, int index, uint32_t baseinst, int loadop, int up, int32_t disp)
+ void
+ emit_ldfstf_uops(StaticInstPtr* microOps, int index, ExtMachInst machInst,
+ bool loadop, bool up, int32_t disp)
{
- StaticInstPtr newInst;
- uint32_t newMachInst;
+ MachInst newMachInst = machInst & 0xf000f000;
if (loadop)
{
- newMachInst = baseinst & 0xfffff000;
- newMachInst |= (disp & 0x0fff);
- newInst = new Ldlo_uop(newMachInst);
- microOps[index++] = newInst;
-
- newMachInst = baseinst & 0xfffff000;
- if (up)
- newMachInst |= ((disp + 4) & 0x0fff);
- else
- newMachInst |= ((disp - 4) & 0x0fff);
- newInst = new Ldhi_uop(newMachInst);
- microOps[index++] = newInst;
-
- newMachInst = baseinst & 0xf000f000;
- newInst = new Mvtd_uop(newMachInst);
- microOps[index++] = newInst;
+ microOps[index++] = new MicroLdrUop(machInst, 19, RN, disp);
+ microOps[index++] =
+ new MicroLdrUop(machInst, 18, RN, disp + (up ? 4 : -4));
+ microOps[index++] = new Mvtd_uop(newMachInst);
}
else
{
- newMachInst = baseinst & 0xf000f000;
- newInst = new Mvfd_uop(newMachInst);
- microOps[index++] = newInst;
-
- newMachInst = baseinst & 0xfffff000;
- newMachInst |= (disp & 0x0fff);
- newInst = new Stlo_uop(newMachInst);
- microOps[index++] = newInst;
-
- newMachInst = baseinst & 0xfffff000;
- if (up)
- newMachInst |= ((disp + 4) & 0x0fff);
- else
- newMachInst |= ((disp - 4) & 0x0fff);
- newInst = new Sthi_uop(newMachInst);
- microOps[index++] = newInst;
+ microOps[index++] = new Mvfd_uop(newMachInst);
+ microOps[index++] = new MicroStrUop(machInst, 19, RN, disp);
+ microOps[index++] =
+ new MicroStrUop(machInst, 18, RN, disp + (up ? 4 : -4));
}
- return 3;
}
}};