ARM: Move the integer microops out of the decoder and into the ISA desc.
This commit is contained in:
parent
4eb18cc07a
commit
70a75ceb84
4 changed files with 96 additions and 69 deletions
|
@ -46,6 +46,23 @@ number_of_ones(int32_t val)
|
||||||
return ones;
|
return ones;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Microops of the form IntRegA = IntRegB op Imm
|
||||||
|
*/
|
||||||
|
class MicroIntOp : public PredOp
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
RegIndex ura, urb;
|
||||||
|
uint8_t imm;
|
||||||
|
|
||||||
|
MicroIntOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
|
||||||
|
RegIndex _ura, RegIndex _urb, uint8_t _imm)
|
||||||
|
: PredOp(mnem, machInst, __opClass),
|
||||||
|
ura(_ura), urb(_urb), imm(_imm)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Arm Macro Memory operations like LDM/STM
|
* Arm Macro Memory operations like LDM/STM
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -41,20 +41,12 @@ decode COND_CODE default Unknown::unknown() {
|
||||||
0xf: decode COND_CODE {
|
0xf: decode COND_CODE {
|
||||||
0x0: decode OPCODE {
|
0x0: decode OPCODE {
|
||||||
// Just a simple trick to allow us to specify our new uops here
|
// Just a simple trick to allow us to specify our new uops here
|
||||||
0x0: PredImmOp::addi_uop({{ Raddr = Rn + rotated_imm; }},
|
|
||||||
'IsMicroop');
|
|
||||||
0x1: PredImmOp::subi_uop({{ Raddr = Rn - rotated_imm; }},
|
|
||||||
'IsMicroop');
|
|
||||||
0x2: ArmLoadMemory::ldr_uop({{ Rd = Mem; }},
|
0x2: ArmLoadMemory::ldr_uop({{ Rd = Mem; }},
|
||||||
{{ EA = Raddr + (up ? disp : -disp); }},
|
{{ EA = Raddr + (up ? disp : -disp); }},
|
||||||
inst_flags = [IsMicroop]);
|
inst_flags = [IsMicroop]);
|
||||||
0x3: ArmStoreMemory::str_uop({{ Mem = Rd; }},
|
0x3: ArmStoreMemory::str_uop({{ Mem = Rd; }},
|
||||||
{{ EA = Raddr + (up ? disp : -disp); }},
|
{{ EA = Raddr + (up ? disp : -disp); }},
|
||||||
inst_flags = [IsMicroop]);
|
inst_flags = [IsMicroop]);
|
||||||
0x4: PredImmOp::addi_rd_uop({{ Rd = Rn + rotated_imm; }},
|
|
||||||
'IsMicroop');
|
|
||||||
0x5: PredImmOp::subi_rd_uop({{ Rd = Rn - rotated_imm; }},
|
|
||||||
'IsMicroop');
|
|
||||||
}
|
}
|
||||||
0x1: decode OPCODE {
|
0x1: decode OPCODE {
|
||||||
0x0: PredIntOp::mvtd_uop({{ Fd.ud = ((uint64_t) Rhi << 32)|Rlo; }},
|
0x0: PredIntOp::mvtd_uop({{ Fd.ud = ((uint64_t) Rhi << 32)|Rlo; }},
|
||||||
|
|
|
@ -27,6 +27,57 @@
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
// Authors: Stephen Hines
|
// Authors: Stephen Hines
|
||||||
|
// Gabe Black
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Integer = Integer op Immediate microops
|
||||||
|
//
|
||||||
|
|
||||||
|
def template MicroIntDeclare {{
|
||||||
|
class %(class_name)s : public %(base_class)s
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
%(class_name)s(ExtMachInst machInst,
|
||||||
|
RegIndex _ura, RegIndex _urb,
|
||||||
|
uint8_t _imm);
|
||||||
|
%(BasicExecDeclare)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)
|
||||||
|
{
|
||||||
|
%(constructor)s;
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
let {{
|
||||||
|
microAddiUopIop = InstObjParams('addi_uop', 'MicroAddiUop',
|
||||||
|
'MicroIntOp',
|
||||||
|
{'code': 'Ra = Rb + imm;',
|
||||||
|
'predicate_test': predicateTest},
|
||||||
|
['IsMicroop'])
|
||||||
|
|
||||||
|
microSubiUopIop = InstObjParams('subi_uop', 'MicroSubiUop',
|
||||||
|
'MicroIntOp',
|
||||||
|
{'code': 'Ra = Rb - imm;',
|
||||||
|
'predicate_test': predicateTest},
|
||||||
|
['IsMicroop'])
|
||||||
|
|
||||||
|
header_output = MicroIntDeclare.subst(microAddiUopIop) + \
|
||||||
|
MicroIntDeclare.subst(microSubiUopIop)
|
||||||
|
decoder_output = MicroIntConstructor.subst(microAddiUopIop) + \
|
||||||
|
MicroIntConstructor.subst(microSubiUopIop)
|
||||||
|
exec_output = PredOpExecute.subst(microAddiUopIop) + \
|
||||||
|
PredOpExecute.subst(microSubiUopIop)
|
||||||
|
}};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -86,13 +137,12 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t newMachInst = 0;
|
// Add 0 to Rn and stick it in Raddr (register 17).
|
||||||
newMachInst = machInst & 0xffff0000;
|
// This is equivalent to a move.
|
||||||
microOps[0] = new Addi_uop(newMachInst);
|
microOps[0] = new MicroAddiUop(machInst, 17, RN, 0);
|
||||||
|
|
||||||
unsigned j = 0;
|
unsigned j = 0;
|
||||||
for (int i = 1; i < ones+1; i++)
|
for (int i = 1; i < ones+1; i++) {
|
||||||
{
|
|
||||||
// Get next available bit for transfer
|
// Get next available bit for transfer
|
||||||
while (! ( regs_to_handle & (1<<j)))
|
while (! ( regs_to_handle & (1<<j)))
|
||||||
j++;
|
j++;
|
||||||
|
@ -106,24 +156,13 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
|
||||||
start_addr -= 4;
|
start_addr -= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writeback)
|
if (writeback) {
|
||||||
{
|
if (up) {
|
||||||
uint32_t newMachInst = machInst & 0xf0000000;
|
microOps[numMicroops-1] =
|
||||||
uint32_t rn = (machInst >> 16) & 0x0f;
|
new MicroAddiUop(machInst, RN, RN, ones * 4);
|
||||||
// 3322 2222 2222 1111 1111 11
|
} else {
|
||||||
// 1098 7654 3210 9876 5432 1098 7654 3210
|
microOps[numMicroops-1] =
|
||||||
// COND 0010 0100 [RN] [RD] 0000 [ IMM ]
|
new MicroSubiUop(machInst, RN, RN, ones * 4);
|
||||||
// sub rn, rn, imm
|
|
||||||
newMachInst |= 0x02400000;
|
|
||||||
newMachInst |= ((rn << 16) | (rn << 12));
|
|
||||||
newMachInst |= (ones << 2);
|
|
||||||
if (up)
|
|
||||||
{
|
|
||||||
microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
microOps[numMicroops-1]->setLastMicroop();
|
microOps[numMicroops-1]->setLastMicroop();
|
||||||
|
@ -166,23 +205,12 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
|
||||||
|
|
||||||
if (writeback)
|
if (writeback)
|
||||||
{
|
{
|
||||||
uint32_t newMachInst = machInst & 0xf0000000;
|
if (up) {
|
||||||
uint32_t rn = (machInst >> 16) & 0x0f;
|
microOps[numMicroops-1] =
|
||||||
// 3322 2222 2222 1111 1111 11
|
new MicroAddiUop(machInst, RN, RN, disp8);
|
||||||
// 1098 7654 3210 9876 5432 1098 7654 3210
|
} else {
|
||||||
// COND 0010 0100 [RN] [RD] 0000 [ IMM ]
|
microOps[numMicroops-1] =
|
||||||
// sub rn, rn, imm
|
new MicroSubiUop(machInst, RN, RN, disp8);
|
||||||
newMachInst |= 0x02400000;
|
|
||||||
newMachInst |= ((rn << 16) | (rn << 12));
|
|
||||||
if (up)
|
|
||||||
{
|
|
||||||
newMachInst |= disp8;
|
|
||||||
microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
newMachInst |= disp8;
|
|
||||||
microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
microOps[numMicroops-1]->setLastMicroop();
|
microOps[numMicroops-1]->setLastMicroop();
|
||||||
|
@ -205,29 +233,15 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
|
||||||
start_addr = 0;
|
start_addr = 0;
|
||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
|
||||||
emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr);
|
emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr);
|
||||||
}
|
|
||||||
|
|
||||||
if (writeback)
|
if (writeback) {
|
||||||
{
|
if (up) {
|
||||||
uint32_t newMachInst = machInst & 0xf0000000;
|
microOps[numMicroops-1] =
|
||||||
uint32_t rn = (machInst >> 16) & 0x0f;
|
new MicroAddiUop(machInst, RN, RN, disp8);
|
||||||
// 3322 2222 2222 1111 1111 11
|
} else {
|
||||||
// 1098 7654 3210 9876 5432 1098 7654 3210
|
microOps[numMicroops-1] =
|
||||||
// COND 0010 0100 [RN] [RD] 0000 [ IMM ]
|
new MicroSubiUop(machInst, RN, RN, disp8);
|
||||||
// sub rn, rn, imm
|
|
||||||
newMachInst |= 0x02400000;
|
|
||||||
newMachInst |= ((rn << 16) | (rn << 12));
|
|
||||||
if (up)
|
|
||||||
{
|
|
||||||
newMachInst |= disp8;
|
|
||||||
microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
newMachInst |= disp8;
|
|
||||||
microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
microOps[numMicroops-1]->setLastMicroop();
|
microOps[numMicroops-1]->setLastMicroop();
|
||||||
|
|
|
@ -56,6 +56,10 @@ def operands {{
|
||||||
'Rlo': ('IntReg', 'uw', '19', 'IsInteger', 8),
|
'Rlo': ('IntReg', 'uw', '19', 'IsInteger', 8),
|
||||||
'LR': ('IntReg', 'uw', '14', 'IsInteger', 9),
|
'LR': ('IntReg', 'uw', '14', 'IsInteger', 9),
|
||||||
|
|
||||||
|
#Register fields for microops
|
||||||
|
'Ra' : ('IntReg', 'uw', 'ura', 'IsInteger', 11),
|
||||||
|
'Rb' : ('IntReg', 'uw', 'urb', 'IsInteger', 12),
|
||||||
|
|
||||||
#General Purpose Floating Point Reg Operands
|
#General Purpose Floating Point Reg Operands
|
||||||
'Fd': ('FloatReg', 'df', 'FD', 'IsFloating', 20),
|
'Fd': ('FloatReg', 'df', 'FD', 'IsFloating', 20),
|
||||||
'Fn': ('FloatReg', 'df', 'FN', 'IsFloating', 21),
|
'Fn': ('FloatReg', 'df', 'FN', 'IsFloating', 21),
|
||||||
|
|
Loading…
Reference in a new issue