ARM: Move the memory microops out of the decoder and into the ISA desc.
This commit is contained in:
parent
70a75ceb84
commit
1d4f338b39
4 changed files with 96 additions and 88 deletions
|
@ -63,6 +63,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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -29,6 +29,67 @@
|
|||
// 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;
|
||||
}
|
||||
}};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Load/store microops
|
||||
//
|
||||
|
||||
def template MicroMemDeclare {{
|
||||
class %(class_name)s : public %(base_class)s
|
||||
{
|
||||
public:
|
||||
%(class_name)s(ExtMachInst machInst,
|
||||
RegIndex _ura, RegIndex _urb,
|
||||
uint8_t _imm);
|
||||
%(BasicExecDeclare)s
|
||||
%(InitiateAccDeclare)s
|
||||
%(CompleteAccDeclare)s
|
||||
};
|
||||
}};
|
||||
|
||||
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)
|
||||
}};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
@ -46,18 +107,6 @@ def template MicroIntDeclare {{
|
|||
};
|
||||
}};
|
||||
|
||||
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)
|
||||
{
|
||||
%(constructor)s;
|
||||
}
|
||||
}};
|
||||
|
||||
let {{
|
||||
microAddiUopIop = InstObjParams('addi_uop', 'MicroAddiUop',
|
||||
'MicroIntOp',
|
||||
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}};
|
||||
|
|
Loading…
Reference in a new issue