}
};
+/**
+ * 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
*/
//
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
}
// 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:
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 {{
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)
}};
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;
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;
}
}};