ARM: Move the integer 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 4eb18cc07a
commit 70a75ceb84
4 changed files with 96 additions and 69 deletions

View file

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

View file

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

View file

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

View file

@ -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),