summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/arm/insts/macromem.hh17
-rw-r--r--src/arch/arm/isa/decoder.isa8
-rw-r--r--src/arch/arm/isa/formats/macromem.isa136
-rw-r--r--src/arch/arm/isa/operands.isa4
4 files changed, 96 insertions, 69 deletions
diff --git a/src/arch/arm/insts/macromem.hh b/src/arch/arm/insts/macromem.hh
index 7b566bb57..c215cdeab 100644
--- a/src/arch/arm/insts/macromem.hh
+++ b/src/arch/arm/insts/macromem.hh
@@ -47,6 +47,23 @@ number_of_ones(int32_t val)
}
/**
+ * 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
*/
class ArmMacroMemoryOp : public PredMacroOp
diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa
index 0cea98a40..fbeb2da22 100644
--- a/src/arch/arm/isa/decoder.isa
+++ b/src/arch/arm/isa/decoder.isa
@@ -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; }},
diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa
index e50e31386..9b3a4f75f 100644
--- a/src/arch/arm/isa/formats/macromem.isa
+++ b/src/arch/arm/isa/formats/macromem.isa
@@ -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();
diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa
index 18295cf61..c9df79e1e 100644
--- a/src/arch/arm/isa/operands.isa
+++ b/src/arch/arm/isa/operands.isa
@@ -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),