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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
|
|
@ -41,20 +41,12 @@ 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
|
||||
0x0: PredImmOp::addi_uop({{ Raddr = Rn + rotated_imm; }},
|
||||
'IsMicroop');
|
||||
0x1: PredImmOp::subi_uop({{ Raddr = Rn - rotated_imm; }},
|
||||
'IsMicroop');
|
||||
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]);
|
||||
0x4: PredImmOp::addi_rd_uop({{ Rd = Rn + rotated_imm; }},
|
||||
'IsMicroop');
|
||||
0x5: PredImmOp::subi_rd_uop({{ Rd = Rn - rotated_imm; }},
|
||||
'IsMicroop');
|
||||
}
|
||||
0x1: decode OPCODE {
|
||||
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.
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
uint32_t newMachInst = 0;
|
||||
newMachInst = machInst & 0xffff0000;
|
||||
microOps[0] = new Addi_uop(newMachInst);
|
||||
// Add 0 to Rn and stick it in Raddr (register 17).
|
||||
// This is equivalent to a move.
|
||||
microOps[0] = new MicroAddiUop(machInst, 17, RN, 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
|
||||
while (! ( regs_to_handle & (1<<j)))
|
||||
j++;
|
||||
|
@ -106,24 +156,13 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
|
|||
start_addr -= 4;
|
||||
}
|
||||
|
||||
if (writeback)
|
||||
{
|
||||
uint32_t newMachInst = machInst & 0xf0000000;
|
||||
uint32_t rn = (machInst >> 16) & 0x0f;
|
||||
// 3322 2222 2222 1111 1111 11
|
||||
// 1098 7654 3210 9876 5432 1098 7654 3210
|
||||
// COND 0010 0100 [RN] [RD] 0000 [ IMM ]
|
||||
// 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);
|
||||
if (writeback) {
|
||||
if (up) {
|
||||
microOps[numMicroops-1] =
|
||||
new MicroAddiUop(machInst, RN, RN, ones * 4);
|
||||
} else {
|
||||
microOps[numMicroops-1] =
|
||||
new MicroSubiUop(machInst, RN, RN, ones * 4);
|
||||
}
|
||||
}
|
||||
microOps[numMicroops-1]->setLastMicroop();
|
||||
|
@ -166,23 +205,12 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
|
|||
|
||||
if (writeback)
|
||||
{
|
||||
uint32_t newMachInst = machInst & 0xf0000000;
|
||||
uint32_t rn = (machInst >> 16) & 0x0f;
|
||||
// 3322 2222 2222 1111 1111 11
|
||||
// 1098 7654 3210 9876 5432 1098 7654 3210
|
||||
// COND 0010 0100 [RN] [RD] 0000 [ IMM ]
|
||||
// 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);
|
||||
if (up) {
|
||||
microOps[numMicroops-1] =
|
||||
new MicroAddiUop(machInst, RN, RN, disp8);
|
||||
} else {
|
||||
microOps[numMicroops-1] =
|
||||
new MicroSubiUop(machInst, RN, RN, disp8);
|
||||
}
|
||||
}
|
||||
microOps[numMicroops-1]->setLastMicroop();
|
||||
|
@ -205,29 +233,15 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
|
|||
start_addr = 0;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr);
|
||||
}
|
||||
|
||||
if (writeback)
|
||||
{
|
||||
uint32_t newMachInst = machInst & 0xf0000000;
|
||||
uint32_t rn = (machInst >> 16) & 0x0f;
|
||||
// 3322 2222 2222 1111 1111 11
|
||||
// 1098 7654 3210 9876 5432 1098 7654 3210
|
||||
// COND 0010 0100 [RN] [RD] 0000 [ IMM ]
|
||||
// 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);
|
||||
if (writeback) {
|
||||
if (up) {
|
||||
microOps[numMicroops-1] =
|
||||
new MicroAddiUop(machInst, RN, RN, disp8);
|
||||
} else {
|
||||
microOps[numMicroops-1] =
|
||||
new MicroSubiUop(machInst, RN, RN, disp8);
|
||||
}
|
||||
}
|
||||
microOps[numMicroops-1]->setLastMicroop();
|
||||
|
|
|
@ -56,6 +56,10 @@ def operands {{
|
|||
'Rlo': ('IntReg', 'uw', '19', 'IsInteger', 8),
|
||||
'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
|
||||
'Fd': ('FloatReg', 'df', 'FD', 'IsFloating', 20),
|
||||
'Fn': ('FloatReg', 'df', 'FN', 'IsFloating', 21),
|
||||
|
|
Loading…
Reference in a new issue