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