From 311f77f33d8a4f59421d4bb740e328ce3b86ea33 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 8 Jul 2009 23:02:19 -0700 Subject: [PATCH] ARM: Add an AddrMode2 format for memory instructions that use address mode 2. --- src/arch/arm/insts/mem.hh | 6 -- src/arch/arm/isa/decoder.isa | 114 +++---------------------------- src/arch/arm/isa/formats/mem.isa | 51 ++++++++++++++ 3 files changed, 59 insertions(+), 112 deletions(-) diff --git a/src/arch/arm/insts/mem.hh b/src/arch/arm/insts/mem.hh index de6e2b954..846089566 100644 --- a/src/arch/arm/insts/mem.hh +++ b/src/arch/arm/insts/mem.hh @@ -68,12 +68,6 @@ class Memory : public PredOp hilo((machInst.immedHi11_8 << 4) | machInst.immedLo3_0), shift_size(machInst.shiftSize), shift(machInst.shift) { - // When Up is not set, then we must subtract by the displacement - if (!up) - { - disp = -disp; - disp8 = -disp8; - } } std::string diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index 7cc0b198f..0cea98a40 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -46,10 +46,10 @@ decode COND_CODE default Unknown::unknown() { 0x1: PredImmOp::subi_uop({{ Raddr = Rn - rotated_imm; }}, 'IsMicroop'); 0x2: ArmLoadMemory::ldr_uop({{ Rd = Mem; }}, - {{ EA = Raddr + disp; }}, + {{ EA = Raddr + (up ? disp : -disp); }}, inst_flags = [IsMicroop]); 0x3: ArmStoreMemory::str_uop({{ Mem = Rd; }}, - {{ EA = Raddr + disp; }}, + {{ EA = Raddr + (up ? disp : -disp); }}, inst_flags = [IsMicroop]); 0x4: PredImmOp::addi_rd_uop({{ Rd = Rn + rotated_imm; }}, 'IsMicroop'); @@ -63,16 +63,16 @@ decode COND_CODE default Unknown::unknown() { Rlo = Fd.ud & 0xffffffff; }}, 'IsMicroop'); 0x2: ArmLoadMemory::ldhi_uop({{ Rhi = Mem; }}, - {{ EA = Rn + disp; }}, + {{ EA = Rn + (up ? disp : -disp); }}, inst_flags = [IsMicroop]); 0x3: ArmLoadMemory::ldlo_uop({{ Rlo = Mem; }}, - {{ EA = Rn + disp; }}, + {{ EA = Rn + (up ? disp : -disp); }}, inst_flags = [IsMicroop]); 0x4: ArmStoreMemory::sthi_uop({{ Mem = Rhi; }}, - {{ EA = Rn + disp; }}, + {{ EA = Rn + (up ? disp : -disp); }}, inst_flags = [IsMicroop]); 0x5: ArmStoreMemory::stlo_uop({{ Mem = Rlo; }}, - {{ EA = Rn + disp; }}, + {{ EA = Rn + (up ? disp : -disp); }}, inst_flags = [IsMicroop]); } default: Unknown::unknown(); // TODO: Ignore other NV space for now @@ -225,107 +225,9 @@ format DataOp { 0xb: WarnUnimpl::mrs_i_spsr(); } } - 0x2: decode PUBWL { - // CAREFUL: - // Can always do EA + disp, since we negate disp using the UP flag - // Post-indexed variants - 0x00,0x08: ArmStoreMemory::str_({{ Mem = Rd; - Rn = Rn + disp; }}, - {{ EA = Rn; }}); - 0x01,0x09: ArmLoadMemory::ldr_l({{ Rn = Rn + disp; - Rd = Mem; }}, - {{ EA = Rn; }}); - 0x04,0x0c: ArmStoreMemory::strb_b({{ Mem.ub = Rd.ub; - Rn = Rn + disp; }}, - {{ EA = Rn; }}); - 0x05,0x0d: ArmLoadMemory::ldrb_bl({{ Rn = Rn + disp; - Rd.ub = Mem.ub; }}, - {{ EA = Rn; }}); - // Pre-indexed variants - 0x10,0x18: ArmStoreMemory::str_p({{ Mem = Rd; }}); - 0x11,0x19: ArmLoadMemory::ldr_pl({{ Rd = Mem; }}); - 0x12,0x1a: ArmStoreMemory::str_pw({{ Mem = Rd; - Rn = Rn + disp; }}); - 0x13,0x1b: ArmLoadMemory::ldr_pwl({{ Rn = Rn + disp; - Rd = Mem; }}); - 0x14,0x1c: ArmStoreMemory::strb_pb({{ Mem.ub = Rd.ub; }}); - 0x15,0x1d: ArmLoadMemory::ldrb_pbl({{ Rd.ub = Mem.ub; }}); - 0x16,0x1e: ArmStoreMemory::strb_pbw({{ Mem.ub = Rd.ub; - Rn = Rn + disp; }}); - 0x17,0x1f: ArmLoadMemory::ldrb_pbwl({{ Rn = Rn + disp; - Rd.ub = Mem.ub; }}); - } + 0x2: AddrMode2::addrMode2(Disp, disp); 0x3: decode OPCODE_4 { - 0: decode PUBWL { - format ArmStoreMemory { - 0x00, 0x02: strr_({{ Mem = Rd; - Rn = Rn - Rm_Imm; }}, - {{ EA = Rn; }}); - 0x04, 0x06: strr_b({{ Mem = Rd.ub; - Rn = Rn - Rm_Imm; }}, - {{ EA = Rn; }}); - 0x08, 0x0a: strr_u({{ Mem = Rd; - Rn = Rn + Rm_Imm; }}, - {{ EA = Rn; }}); - 0x0c, 0x0e: strr_ub({{ Mem.ub = Rd.ub; - Rn = Rn + Rm_Imm; }}, - {{ EA = Rn; }}); - 0x10: strr_p({{ Mem = Rd; }}, - {{ EA = Rn - Rm_Imm; }}); - 0x12: strr_pw({{ Mem = Rd; - Rn = Rn - Rm_Imm; }}, - {{ EA = Rn - Rm_Imm; }}); - 0x14: strr_pb({{ Mem.ub = Rd.ub; }}, - {{ EA = Rn - Rm_Imm; }}); - 0x16: strr_pbw({{ Mem.ub = Rd.ub; - Rn = Rn - Rm_Imm; }}, - {{ EA = Rn - Rm_Imm; }}); - 0x18: strr_pu({{ Mem = Rd; }}, - {{ EA = Rn + Rm_Imm; }}); - 0x1a: strr_puw({{ Mem = Rd; - Rn = Rn + Rm_Imm; }}, - {{ EA = Rn + Rm_Imm; }}); - 0x1c: strr_pub({{ Mem.ub = Rd; }}, - {{ EA = Rn + Rm_Imm; }}); - 0x1e: strr_pubw({{ Mem.ub = Rd; - Rn = Rn + Rm_Imm; }}, - {{ EA = Rn + Rm_Imm; }}); - } - format ArmLoadMemory { - 0x01,0x03: ldrr_l({{ Rd = Mem; - Rn = Rn - Rm_Imm; }}, - {{ EA = Rn; }}); - 0x05,0x07: ldrr_bl({{ Rd = Mem.ub; - Rn = Rn - Rm_Imm; }}, - {{ EA = Rn; }}); - 0x09,0x0b: ldrr_ul({{ Rd = Mem; - Rn = Rn + Rm_Imm; }}, - {{ EA = Rn; }}); - 0x0d,0x0f: ldrr_ubl({{ Rd = Mem.ub; - Rn = Rn + Rm_Imm; }}, - {{ EA = Rn; }}); - 0x11: ldrr_pl({{ Rd = Mem; }}, - {{ EA = Rn - Rm_Imm; }}); - 0x13: ldrr_pwl({{ Rd = Mem; - Rn = Rn - Rm_Imm; }}, - {{ EA = Rn - Rm_Imm; }}); - 0x15: ldrr_pbl({{ Rd = Mem.ub; }}, - {{ EA = Rn - Rm_Imm; }}); - 0x17: ldrr_pbwl({{ Rd = Mem.ub; - Rn = Rn - Rm_Imm; }}, - {{ EA = Rn - Rm_Imm; }}); - 0x19: ldrr_pul({{ Rd = Mem; }}, - {{ EA = Rn + Rm_Imm; }}); - 0x1b: ldrr_puwl({{ Rd = Mem; - Rn = Rn + Rm_Imm; }}, - {{ EA = Rn + Rm_Imm; }}); - 0x1d: ldrr_publ({{ Rd = Mem.ub; }}, - {{ EA = Rn + Rm_Imm; }}); - 0x1f: ldrr_pubwl({{ Rd = Mem.ub; - Rn = Rn + Rm_Imm; }}, - {{ EA = Rn + Rm_Imm; }}); - } - } + 0: AddrMode2::addrMode2(Shift, Rm_Imm); 1: decode MEDIA_OPCODE { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7: WarnUnimpl::parallel_add_subtract_instructions(); 0x8: decode MISC_OPCODE { diff --git a/src/arch/arm/isa/formats/mem.isa b/src/arch/arm/isa/formats/mem.isa index 41fd0552c..e3eed5df1 100644 --- a/src/arch/arm/isa/formats/mem.isa +++ b/src/arch/arm/isa/formats/mem.isa @@ -459,6 +459,26 @@ let {{ def buildPUBWLCase(p, u, b, w, l): return (p << 4) + (u << 3) + (b << 2) + (w << 1) + (l << 0) + def buildMode2Inst(p, u, b, w, l, suffix, offset): + mnem = ("str", "ldr")[l] + op = ("-", "+")[u] + offset = op + ArmGenericCodeSubs(offset); + mem = ("Mem", "Mem.ub")[b] + code = ("%s = Rd;", "Rd = %s;")[l] % mem + ea_code = "EA = Rn %s;" % ("", offset)[p] + if p == 0 or w == 1: + code += "Rn = Rn %s;" % offset + if p == 0 and w == 0: + # Here's where we'll tack on a flag to make this a usermode access. + mnem += "t" + type = ("Store", "Load")[l] + suffix = "_%s_P%dU%dB%dW%d" % (suffix, p, u, b, w) + if b == 1: + mnem += "b" + return LoadStoreBase(mnem, mnem.capitalize() + suffix, + ea_code, code, mem_flags = [], inst_flags = [], + exec_template_base = type.capitalize()) + def buildMode3Inst(p, u, i, w, type, code, mnem): op = ("-", "+")[u] offset = ("%s Rm", "%s hilo")[i] % op @@ -471,6 +491,37 @@ let {{ exec_template_base = type.capitalize()) }}; +def format AddrMode2(suffix, offset) {{ + header_output = decoder_output = exec_output = "" + decode_block = "switch(PUBWL) {\n" + + # Loop over all the values of p, u, b, w and l and build instructions and + # a decode block for them. + for p in (0, 1): + for u in (0, 1): + for b in (0, 1): + for w in (0, 1): + for l in (0, 1): + (new_header_output, + new_decoder_output, + new_decode_block, + new_exec_output) = buildMode2Inst(p, u, b, w, l, + suffix, offset) + header_output += new_header_output + decoder_output += new_decoder_output + exec_output += new_exec_output + decode_block += ''' + case %#x: + {%s} + break; + ''' % (buildPUBWLCase(p,u,b,w,l), new_decode_block) + decode_block += ''' + default: + return new Unknown(machInst); + break; + }''' +}}; + def format AddrMode3(l0Type, l0Code, l1Type, l1Code) {{ l0Code = ArmGenericCodeSubs(l0Code); l1Code = ArmGenericCodeSubs(l1Code);