ARM: Move the memory microops out of the decoder and into the ISA desc.

This commit is contained in:
Gabe Black 2009-07-08 23:02:19 -07:00
parent 70a75ceb84
commit 1d4f338b39
4 changed files with 96 additions and 88 deletions

View file

@ -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
*/

View file

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

View file

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

View file

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