From f154da9e12608589e8d5f0508f908a0c3e88a1bb Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Thu, 15 Jan 2015 11:54:00 -0700 Subject: Imported Upstream version 1.4 --- src/cmd/objdump/Makefile | 10 - src/cmd/objdump/armasm.go | 10821 ------------------------------ src/cmd/objdump/elf.go | 65 - src/cmd/objdump/macho.go | 77 - src/cmd/objdump/main.go | 456 +- src/cmd/objdump/objdump_test.go | 122 +- src/cmd/objdump/pe.go | 99 - src/cmd/objdump/plan9obj.go | 63 - src/cmd/objdump/x86.go | 13800 -------------------------------------- 9 files changed, 43 insertions(+), 25470 deletions(-) delete mode 100644 src/cmd/objdump/Makefile delete mode 100644 src/cmd/objdump/armasm.go delete mode 100644 src/cmd/objdump/elf.go delete mode 100644 src/cmd/objdump/macho.go delete mode 100644 src/cmd/objdump/pe.go delete mode 100644 src/cmd/objdump/plan9obj.go delete mode 100644 src/cmd/objdump/x86.go (limited to 'src/cmd/objdump') diff --git a/src/cmd/objdump/Makefile b/src/cmd/objdump/Makefile deleted file mode 100644 index 1b66c26ba..000000000 --- a/src/cmd/objdump/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -all: x86.go armasm.go - -x86.go: bundle - ./bundle -p main -x x86_ rsc.io/x86/x86asm | gofmt >x86.go - -armasm.go: bundle - ./bundle -p main -x arm_ rsc.io/arm/armasm | gofmt >armasm.go - -bundle: - go build -o bundle code.google.com/p/rsc/cmd/bundle diff --git a/src/cmd/objdump/armasm.go b/src/cmd/objdump/armasm.go deleted file mode 100644 index 764a3689e..000000000 --- a/src/cmd/objdump/armasm.go +++ /dev/null @@ -1,10821 +0,0 @@ -// DO NOT EDIT. Generated by code.google.com/p/rsc/cmd/bundle -// bundle -p main -x arm_ rsc.io/arm/armasm - -/* decode.go */ - -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "bytes" - "encoding/binary" - "fmt" - "io" - "strings" -) - -// An instFormat describes the format of an instruction encoding. -// An instruction with 32-bit value x matches the format if x&mask == value -// and the condition matches. -// The condition matches if x>>28 == 0xF && value>>28==0xF -// or if x>>28 != 0xF and value>>28 == 0. -// If x matches the format, then the rest of the fields describe how to interpret x. -// The opBits describe bits that should be extracted from x and added to the opcode. -// For example opBits = 0x1234 means that the value -// (2 bits at offset 1) followed by (4 bits at offset 3) -// should be added to op. -// Finally the args describe how to decode the instruction arguments. -// args is stored as a fixed-size array; if there are fewer than len(args) arguments, -// args[i] == 0 marks the end of the argument list. -type arm_instFormat struct { - mask uint32 - value uint32 - priority int8 - op arm_Op - opBits uint64 - args arm_instArgs -} - -type arm_instArgs [4]arm_instArg - -var ( - arm_errMode = fmt.Errorf("unsupported execution mode") - arm_errShort = fmt.Errorf("truncated instruction") - arm_errUnknown = fmt.Errorf("unknown instruction") -) - -var arm_decoderCover []bool - -// Decode decodes the leading bytes in src as a single instruction. -func arm_Decode(src []byte, mode arm_Mode) (inst arm_Inst, err error) { - if mode != arm_ModeARM { - return arm_Inst{}, arm_errMode - } - if len(src) < 4 { - return arm_Inst{}, arm_errShort - } - - if arm_decoderCover == nil { - arm_decoderCover = make([]bool, len(arm_instFormats)) - } - - x := binary.LittleEndian.Uint32(src) - - // The instFormat table contains both conditional and unconditional instructions. - // Considering only the top 4 bits, the conditional instructions use mask=0, value=0, - // while the unconditional instructions use mask=f, value=f. - // Prepare a version of x with the condition cleared to 0 in conditional instructions - // and then assume mask=f during matching. - const condMask = 0xf0000000 - xNoCond := x - if x&condMask != condMask { - xNoCond &^= condMask - } - var priority int8 -Search: - for i := range arm_instFormats { - f := &arm_instFormats[i] - if xNoCond&(f.mask|condMask) != f.value || f.priority <= priority { - continue - } - delta := uint32(0) - deltaShift := uint(0) - for opBits := f.opBits; opBits != 0; opBits >>= 16 { - n := uint(opBits & 0xFF) - off := uint((opBits >> 8) & 0xFF) - delta |= (x >> off) & (1<> 8) & (1<<4 - 1)) - case arm_arg_R_12: - return arm_Reg((x >> 12) & (1<<4 - 1)) - case arm_arg_R_16: - return arm_Reg((x >> 16) & (1<<4 - 1)) - - case arm_arg_R_12_nzcv: - r := arm_Reg((x >> 12) & (1<<4 - 1)) - if r == arm_R15 { - return arm_APSR_nzcv - } - return r - - case arm_arg_R_16_WB: - mode := arm_AddrLDM - if (x>>21)&1 != 0 { - mode = arm_AddrLDM_WB - } - return arm_Mem{Base: arm_Reg((x >> 16) & (1<<4 - 1)), Mode: mode} - - case arm_arg_R_rotate: - Rm := arm_Reg(x & (1<<4 - 1)) - typ, count := arm_decodeShift(x) - // ROR #0 here means ROR #0, but decodeShift rewrites to RRX #1. - if typ == arm_RotateRightExt { - return arm_Reg(Rm) - } - return arm_RegShift{Rm, typ, uint8(count)} - - case arm_arg_R_shift_R: - Rm := arm_Reg(x & (1<<4 - 1)) - Rs := arm_Reg((x >> 8) & (1<<4 - 1)) - typ := arm_Shift((x >> 5) & (1<<2 - 1)) - return arm_RegShiftReg{Rm, typ, Rs} - - case arm_arg_R_shift_imm: - Rm := arm_Reg(x & (1<<4 - 1)) - typ, count := arm_decodeShift(x) - if typ == arm_ShiftLeft && count == 0 { - return arm_Reg(Rm) - } - return arm_RegShift{Rm, typ, uint8(count)} - - case arm_arg_R1_0: - return arm_Reg((x & (1<<4 - 1))) - case arm_arg_R1_12: - return arm_Reg(((x >> 12) & (1<<4 - 1))) - case arm_arg_R2_0: - return arm_Reg((x & (1<<4 - 1)) | 1) - case arm_arg_R2_12: - return arm_Reg(((x >> 12) & (1<<4 - 1)) | 1) - - case arm_arg_SP: - return arm_SP - - case arm_arg_Sd_Dd: - v := (x >> 12) & (1<<4 - 1) - vx := (x >> 22) & 1 - sz := (x >> 8) & 1 - if sz != 0 { - return arm_D0 + arm_Reg(vx<<4+v) - } else { - return arm_S0 + arm_Reg(v<<1+vx) - } - - case arm_arg_Dd_Sd: - return arm_decodeArg(arm_arg_Sd_Dd, x^(1<<8)) - - case arm_arg_Sd: - v := (x >> 12) & (1<<4 - 1) - vx := (x >> 22) & 1 - return arm_S0 + arm_Reg(v<<1+vx) - - case arm_arg_Sm_Dm: - v := (x >> 0) & (1<<4 - 1) - vx := (x >> 5) & 1 - sz := (x >> 8) & 1 - if sz != 0 { - return arm_D0 + arm_Reg(vx<<4+v) - } else { - return arm_S0 + arm_Reg(v<<1+vx) - } - - case arm_arg_Sm: - v := (x >> 0) & (1<<4 - 1) - vx := (x >> 5) & 1 - return arm_S0 + arm_Reg(v<<1+vx) - - case arm_arg_Dn_half: - v := (x >> 16) & (1<<4 - 1) - vx := (x >> 7) & 1 - return arm_RegX{arm_D0 + arm_Reg(vx<<4+v), int((x >> 21) & 1)} - - case arm_arg_Sn_Dn: - v := (x >> 16) & (1<<4 - 1) - vx := (x >> 7) & 1 - sz := (x >> 8) & 1 - if sz != 0 { - return arm_D0 + arm_Reg(vx<<4+v) - } else { - return arm_S0 + arm_Reg(v<<1+vx) - } - - case arm_arg_Sn: - v := (x >> 16) & (1<<4 - 1) - vx := (x >> 7) & 1 - return arm_S0 + arm_Reg(v<<1+vx) - - case arm_arg_const: - v := x & (1<<8 - 1) - rot := (x >> 8) & (1<<4 - 1) * 2 - if rot > 0 && v&3 == 0 { - // could rotate less - return arm_ImmAlt{uint8(v), uint8(rot)} - } - if rot >= 24 && ((v<<(32-rot))&0xFF)>>(32-rot) == v { - // could wrap around to rot==0. - return arm_ImmAlt{uint8(v), uint8(rot)} - } - return arm_Imm(v>>rot | v<<(32-rot)) - - case arm_arg_endian: - return arm_Endian((x >> 9) & 1) - - case arm_arg_fbits: - return arm_Imm((16 << ((x >> 7) & 1)) - ((x&(1<<4-1))<<1 | (x>>5)&1)) - - case arm_arg_fp_0: - return arm_Imm(0) - - case arm_arg_imm24: - return arm_Imm(x & (1<<24 - 1)) - - case arm_arg_imm5: - return arm_Imm((x >> 7) & (1<<5 - 1)) - - case arm_arg_imm5_32: - x = (x >> 7) & (1<<5 - 1) - if x == 0 { - x = 32 - } - return arm_Imm(x) - - case arm_arg_imm5_nz: - x = (x >> 7) & (1<<5 - 1) - if x == 0 { - return nil - } - return arm_Imm(x) - - case arm_arg_imm_4at16_12at0: - return arm_Imm((x>>16)&(1<<4-1)<<12 | x&(1<<12-1)) - - case arm_arg_imm_12at8_4at0: - return arm_Imm((x>>8)&(1<<12-1)<<4 | x&(1<<4-1)) - - case arm_arg_imm_vfp: - x = (x>>16)&(1<<4-1)<<4 | x&(1<<4-1) - return arm_Imm(x) - - case arm_arg_label24: - imm := (x & (1<<24 - 1)) << 2 - return arm_PCRel(int32(imm<<6) >> 6) - - case arm_arg_label24H: - h := (x >> 24) & 1 - imm := (x&(1<<24-1))<<2 | h<<1 - return arm_PCRel(int32(imm<<6) >> 6) - - case arm_arg_label_m_12: - d := int32(x & (1<<12 - 1)) - return arm_Mem{Base: arm_PC, Mode: arm_AddrOffset, Offset: int16(-d)} - - case arm_arg_label_p_12: - d := int32(x & (1<<12 - 1)) - return arm_Mem{Base: arm_PC, Mode: arm_AddrOffset, Offset: int16(d)} - - case arm_arg_label_pm_12: - d := int32(x & (1<<12 - 1)) - u := (x >> 23) & 1 - if u == 0 { - d = -d - } - return arm_Mem{Base: arm_PC, Mode: arm_AddrOffset, Offset: int16(d)} - - case arm_arg_label_pm_4_4: - d := int32((x>>8)&(1<<4-1)<<4 | x&(1<<4-1)) - u := (x >> 23) & 1 - if u == 0 { - d = -d - } - return arm_PCRel(d) - - case arm_arg_lsb_width: - lsb := (x >> 7) & (1<<5 - 1) - msb := (x >> 16) & (1<<5 - 1) - if msb < lsb || msb >= 32 { - return nil - } - return arm_Imm(msb + 1 - lsb) - - case arm_arg_mem_R: - Rn := arm_Reg((x >> 16) & (1<<4 - 1)) - return arm_Mem{Base: Rn, Mode: arm_AddrOffset} - - case arm_arg_mem_R_pm_R_postindex: - // Treat [],+/- like [,+/-{,}]{!} - // by forcing shift bits to <<0 and P=0, W=0 (postindex=true). - return arm_decodeArg(arm_arg_mem_R_pm_R_shift_imm_W, x&^((1<<7-1)<<5|1<<24|1<<21)) - - case arm_arg_mem_R_pm_R_W: - // Treat [,+/-]{!} like [,+/-{,}]{!} - // by forcing shift bits to <<0. - return arm_decodeArg(arm_arg_mem_R_pm_R_shift_imm_W, x&^((1<<7-1)<<5)) - - case arm_arg_mem_R_pm_R_shift_imm_offset: - // Treat [],+/-{,} like [,+/-{,}]{!} - // by forcing P=1, W=0 (index=false, wback=false). - return arm_decodeArg(arm_arg_mem_R_pm_R_shift_imm_W, x&^(1<<21)|1<<24) - - case arm_arg_mem_R_pm_R_shift_imm_postindex: - // Treat [],+/-{,} like [,+/-{,}]{!} - // by forcing P=0, W=0 (postindex=true). - return arm_decodeArg(arm_arg_mem_R_pm_R_shift_imm_W, x&^(1<<24|1<<21)) - - case arm_arg_mem_R_pm_R_shift_imm_W: - Rn := arm_Reg((x >> 16) & (1<<4 - 1)) - Rm := arm_Reg(x & (1<<4 - 1)) - typ, count := arm_decodeShift(x) - u := (x >> 23) & 1 - w := (x >> 21) & 1 - p := (x >> 24) & 1 - if p == 0 && w == 1 { - return nil - } - sign := int8(+1) - if u == 0 { - sign = -1 - } - mode := arm_AddrMode(uint8(p<<1) | uint8(w^1)) - return arm_Mem{Base: Rn, Mode: mode, Sign: sign, Index: Rm, Shift: typ, Count: count} - - case arm_arg_mem_R_pm_imm12_offset: - // Treat [,#+/-] like [{,#+/-}]{!} - // by forcing P=1, W=0 (index=false, wback=false). - return arm_decodeArg(arm_arg_mem_R_pm_imm12_W, x&^(1<<21)|1<<24) - - case arm_arg_mem_R_pm_imm12_postindex: - // Treat [],#+/- like [{,#+/-}]{!} - // by forcing P=0, W=0 (postindex=true). - return arm_decodeArg(arm_arg_mem_R_pm_imm12_W, x&^(1<<24|1<<21)) - - case arm_arg_mem_R_pm_imm12_W: - Rn := arm_Reg((x >> 16) & (1<<4 - 1)) - u := (x >> 23) & 1 - w := (x >> 21) & 1 - p := (x >> 24) & 1 - if p == 0 && w == 1 { - return nil - } - sign := int8(+1) - if u == 0 { - sign = -1 - } - imm := int16(x & (1<<12 - 1)) - mode := arm_AddrMode(uint8(p<<1) | uint8(w^1)) - return arm_Mem{Base: Rn, Mode: mode, Offset: int16(sign) * imm} - - case arm_arg_mem_R_pm_imm8_postindex: - // Treat [],#+/- like [{,#+/-}]{!} - // by forcing P=0, W=0 (postindex=true). - return arm_decodeArg(arm_arg_mem_R_pm_imm8_W, x&^(1<<24|1<<21)) - - case arm_arg_mem_R_pm_imm8_W: - Rn := arm_Reg((x >> 16) & (1<<4 - 1)) - u := (x >> 23) & 1 - w := (x >> 21) & 1 - p := (x >> 24) & 1 - if p == 0 && w == 1 { - return nil - } - sign := int8(+1) - if u == 0 { - sign = -1 - } - imm := int16((x>>8)&(1<<4-1)<<4 | x&(1<<4-1)) - mode := arm_AddrMode(uint8(p<<1) | uint8(w^1)) - return arm_Mem{Base: Rn, Mode: mode, Offset: int16(sign) * imm} - - case arm_arg_mem_R_pm_imm8at0_offset: - Rn := arm_Reg((x >> 16) & (1<<4 - 1)) - u := (x >> 23) & 1 - sign := int8(+1) - if u == 0 { - sign = -1 - } - imm := int16(x&(1<<8-1)) << 2 - return arm_Mem{Base: Rn, Mode: arm_AddrOffset, Offset: int16(sign) * imm} - - case arm_arg_option: - return arm_Imm(x & (1<<4 - 1)) - - case arm_arg_registers: - return arm_RegList(x & (1<<16 - 1)) - - case arm_arg_registers2: - x &= 1<<16 - 1 - n := 0 - for i := 0; i < 16; i++ { - if x>>uint(i)&1 != 0 { - n++ - } - } - if n < 2 { - return nil - } - return arm_RegList(x) - - case arm_arg_registers1: - Rt := (x >> 12) & (1<<4 - 1) - return arm_RegList(1 << Rt) - - case arm_arg_satimm4: - return arm_Imm((x >> 16) & (1<<4 - 1)) - - case arm_arg_satimm5: - return arm_Imm((x >> 16) & (1<<5 - 1)) - - case arm_arg_satimm4m1: - return arm_Imm((x>>16)&(1<<4-1) + 1) - - case arm_arg_satimm5m1: - return arm_Imm((x>>16)&(1<<5-1) + 1) - - case arm_arg_widthm1: - return arm_Imm((x>>16)&(1<<5-1) + 1) - - } -} - -// decodeShift decodes the shift-by-immediate encoded in x. -func arm_decodeShift(x uint32) (arm_Shift, uint8) { - count := (x >> 7) & (1<<5 - 1) - typ := arm_Shift((x >> 5) & (1<<2 - 1)) - switch typ { - case arm_ShiftRight, arm_ShiftRightSigned: - if count == 0 { - count = 32 - } - case arm_RotateRight: - if count == 0 { - typ = arm_RotateRightExt - count = 1 - } - } - return typ, uint8(count) -} - -/* gnu.go */ - -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -var arm_saveDot = strings.NewReplacer( - ".F16", "_dot_F16", - ".F32", "_dot_F32", - ".F64", "_dot_F64", - ".S32", "_dot_S32", - ".U32", "_dot_U32", - ".FXS", "_dot_S", - ".FXU", "_dot_U", - ".32", "_dot_32", -) - -// GNUSyntax returns the GNU assembler syntax for the instruction, as defined by GNU binutils. -// This form typically matches the syntax defined in the ARM Reference Manual. -func arm_GNUSyntax(inst arm_Inst) string { - var buf bytes.Buffer - op := inst.Op.String() - op = arm_saveDot.Replace(op) - op = strings.Replace(op, ".", "", -1) - op = strings.Replace(op, "_dot_", ".", -1) - op = strings.ToLower(op) - buf.WriteString(op) - sep := " " - for i, arg := range inst.Args { - if arg == nil { - break - } - text := arm_gnuArg(&inst, i, arg) - if text == "" { - continue - } - buf.WriteString(sep) - sep = ", " - buf.WriteString(text) - } - return buf.String() -} - -func arm_gnuArg(inst *arm_Inst, argIndex int, arg arm_Arg) string { - switch inst.Op &^ 15 { - case arm_LDRD_EQ, arm_LDREXD_EQ, arm_STRD_EQ: - if argIndex == 1 { - // second argument in consecutive pair not printed - return "" - } - case arm_STREXD_EQ: - if argIndex == 2 { - // second argument in consecutive pair not printed - return "" - } - } - - switch arg := arg.(type) { - case arm_Imm: - switch inst.Op &^ 15 { - case arm_BKPT_EQ: - return fmt.Sprintf("%#04x", uint32(arg)) - case arm_SVC_EQ: - return fmt.Sprintf("%#08x", uint32(arg)) - } - return fmt.Sprintf("#%d", int32(arg)) - - case arm_ImmAlt: - return fmt.Sprintf("#%d, %d", arg.Val, arg.Rot) - - case arm_Mem: - R := arm_gnuArg(inst, -1, arg.Base) - X := "" - if arg.Sign != 0 { - X = "" - if arg.Sign < 0 { - X = "-" - } - X += arm_gnuArg(inst, -1, arg.Index) - if arg.Shift == arm_ShiftLeft && arg.Count == 0 { - // nothing - } else if arg.Shift == arm_RotateRightExt { - X += ", rrx" - } else { - X += fmt.Sprintf(", %s #%d", strings.ToLower(arg.Shift.String()), arg.Count) - } - } else { - X = fmt.Sprintf("#%d", arg.Offset) - } - - switch arg.Mode { - case arm_AddrOffset: - if X == "#0" { - return fmt.Sprintf("[%s]", R) - } - return fmt.Sprintf("[%s, %s]", R, X) - case arm_AddrPreIndex: - return fmt.Sprintf("[%s, %s]!", R, X) - case arm_AddrPostIndex: - return fmt.Sprintf("[%s], %s", R, X) - case arm_AddrLDM: - if X == "#0" { - return R - } - case arm_AddrLDM_WB: - if X == "#0" { - return R + "!" - } - } - return fmt.Sprintf("[%s Mode(%d) %s]", R, int(arg.Mode), X) - - case arm_PCRel: - return fmt.Sprintf(".%+#x", int32(arg)+4) - - case arm_Reg: - switch inst.Op &^ 15 { - case arm_LDREX_EQ: - if argIndex == 0 { - return fmt.Sprintf("r%d", int32(arg)) - } - } - switch arg { - case arm_R10: - return "sl" - case arm_R11: - return "fp" - case arm_R12: - return "ip" - } - - case arm_RegList: - var buf bytes.Buffer - fmt.Fprintf(&buf, "{") - sep := "" - for i := 0; i < 16; i++ { - if arg&(1<= arm_Op(len(arm_opstr)) || arm_opstr[op] == "" { - return fmt.Sprintf("Op(%d)", int(op)) - } - return arm_opstr[op] -} - -// An Inst is a single instruction. -type arm_Inst struct { - Op arm_Op // Opcode mnemonic - Enc uint32 // Raw encoding bits. - Len int // Length of encoding in bytes. - Args arm_Args // Instruction arguments, in ARM manual order. -} - -func (i arm_Inst) String() string { - var buf bytes.Buffer - buf.WriteString(i.Op.String()) - for j, arg := range i.Args { - if arg == nil { - break - } - if j == 0 { - buf.WriteString(" ") - } else { - buf.WriteString(", ") - } - buf.WriteString(arg.String()) - } - return buf.String() -} - -// An Args holds the instruction arguments. -// If an instruction has fewer than 4 arguments, -// the final elements in the array are nil. -type arm_Args [4]arm_Arg - -// An Arg is a single instruction argument, one of these types: -// Endian, Imm, Mem, PCRel, Reg, RegList, RegShift, RegShiftReg. -type arm_Arg interface { - IsArg() - String() string -} - -type arm_Float32Imm float32 - -func (arm_Float32Imm) IsArg() {} - -func (f arm_Float32Imm) String() string { - return fmt.Sprintf("#%v", float32(f)) -} - -type arm_Float64Imm float32 - -func (arm_Float64Imm) IsArg() {} - -func (f arm_Float64Imm) String() string { - return fmt.Sprintf("#%v", float64(f)) -} - -// An Imm is an integer constant. -type arm_Imm uint32 - -func (arm_Imm) IsArg() {} - -func (i arm_Imm) String() string { - return fmt.Sprintf("#%#x", uint32(i)) -} - -// A ImmAlt is an alternate encoding of an integer constant. -type arm_ImmAlt struct { - Val uint8 - Rot uint8 -} - -func (arm_ImmAlt) IsArg() {} - -func (i arm_ImmAlt) Imm() arm_Imm { - v := uint32(i.Val) - r := uint(i.Rot) - return arm_Imm(v>>r | v<<(32-r)) -} - -func (i arm_ImmAlt) String() string { - return fmt.Sprintf("#%#x, %d", i.Val, i.Rot) -} - -// A Label is a text (code) address. -type arm_Label uint32 - -func (arm_Label) IsArg() {} - -func (i arm_Label) String() string { - return fmt.Sprintf("%#x", uint32(i)) -} - -// A Reg is a single register. -// The zero value denotes R0, not the absence of a register. -type arm_Reg uint8 - -const ( - arm_R0 arm_Reg = iota - arm_R1 - arm_R2 - arm_R3 - arm_R4 - arm_R5 - arm_R6 - arm_R7 - arm_R8 - arm_R9 - arm_R10 - arm_R11 - arm_R12 - arm_R13 - arm_R14 - arm_R15 - - arm_S0 - arm_S1 - arm_S2 - arm_S3 - arm_S4 - arm_S5 - arm_S6 - arm_S7 - arm_S8 - arm_S9 - arm_S10 - arm_S11 - arm_S12 - arm_S13 - arm_S14 - arm_S15 - arm_S16 - arm_S17 - arm_S18 - arm_S19 - arm_S20 - arm_S21 - arm_S22 - arm_S23 - arm_S24 - arm_S25 - arm_S26 - arm_S27 - arm_S28 - arm_S29 - arm_S30 - arm_S31 - - arm_D0 - arm_D1 - arm_D2 - arm_D3 - arm_D4 - arm_D5 - arm_D6 - arm_D7 - arm_D8 - arm_D9 - arm_D10 - arm_D11 - arm_D12 - arm_D13 - arm_D14 - arm_D15 - arm_D16 - arm_D17 - arm_D18 - arm_D19 - arm_D20 - arm_D21 - arm_D22 - arm_D23 - arm_D24 - arm_D25 - arm_D26 - arm_D27 - arm_D28 - arm_D29 - arm_D30 - arm_D31 - - arm_APSR - arm_APSR_nzcv - arm_FPSCR - - arm_SP = arm_R13 - arm_LR = arm_R14 - arm_PC = arm_R15 -) - -func (arm_Reg) IsArg() {} - -func (r arm_Reg) String() string { - switch r { - case arm_APSR: - return "APSR" - case arm_APSR_nzcv: - return "APSR_nzcv" - case arm_FPSCR: - return "FPSCR" - case arm_SP: - return "SP" - case arm_PC: - return "PC" - case arm_LR: - return "LR" - } - if arm_R0 <= r && r <= arm_R15 { - return fmt.Sprintf("R%d", int(r-arm_R0)) - } - if arm_S0 <= r && r <= arm_S31 { - return fmt.Sprintf("S%d", int(r-arm_S0)) - } - if arm_D0 <= r && r <= arm_D31 { - return fmt.Sprintf("D%d", int(r-arm_D0)) - } - return fmt.Sprintf("Reg(%d)", int(r)) -} - -// A RegX represents a fraction of a multi-value register. -// The Index field specifies the index number, -// but the size of the fraction is not specified. -// It must be inferred from the instruction and the register type. -// For example, in a VMOV instruction, RegX{D5, 1} represents -// the top 32 bits of the 64-bit D5 register. -type arm_RegX struct { - Reg arm_Reg - Index int -} - -func (arm_RegX) IsArg() {} - -func (r arm_RegX) String() string { - return fmt.Sprintf("%s[%d]", r.Reg, r.Index) -} - -// A RegList is a register list. -// Bits at indexes x = 0 through 15 indicate whether the corresponding Rx register is in the list. -type arm_RegList uint16 - -func (arm_RegList) IsArg() {} - -func (r arm_RegList) String() string { - var buf bytes.Buffer - fmt.Fprintf(&buf, "{") - sep := "" - for i := 0; i < 16; i++ { - if r&(1< is a lie; the assembler uses @> 0 -// instead of @x> 1, but i wanted to be clear that it -// was a different operation (rotate right extended, not rotate right). -var arm_plan9Shift = []string{"<<", ">>", "->", "@>", "@x>"} - -func arm_plan9Arg(inst *arm_Inst, pc uint64, symname func(uint64) (string, uint64), arg arm_Arg) string { - switch a := arg.(type) { - case arm_Endian: - - case arm_Imm: - return fmt.Sprintf("$%d", int(a)) - - case arm_Mem: - - case arm_PCRel: - addr := uint32(pc) + 8 + uint32(a) - if s, base := symname(uint64(addr)); s != "" && uint64(addr) == base { - return fmt.Sprintf("%s(SB)", s) - } - return fmt.Sprintf("%#x", addr) - - case arm_Reg: - if a < 16 { - return fmt.Sprintf("R%d", int(a)) - } - - case arm_RegList: - var buf bytes.Buffer - start := -2 - end := -2 - fmt.Fprintf(&buf, "[") - flush := func() { - if start >= 0 { - if buf.Len() > 1 { - fmt.Fprintf(&buf, ",") - } - if start == end { - fmt.Fprintf(&buf, "R%d", start) - } else { - fmt.Fprintf(&buf, "R%d-R%d", start, end) - } - } - } - for i := 0; i < 16; i++ { - if a&(1< ,,# cond:4|0|0|1|0|1|0|1|S|Rn:4|Rd:4|imm12:12 - {0x0fe00090, 0x00a00010, 4, arm_ADC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}}, // ADC{S} ,,, cond:4|0|0|0|0|1|0|1|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4 - {0x0fe00010, 0x00a00000, 2, arm_ADC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}}, // ADC{S} ,,{,} cond:4|0|0|0|0|1|0|1|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4 - {0x0fe00000, 0x02800000, 2, arm_ADD_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}}, // ADD{S} ,,# cond:4|0|0|1|0|1|0|0|S|Rn:4|Rd:4|imm12:12 - {0x0fe00090, 0x00800010, 4, arm_ADD_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}}, // ADD{S} ,,, cond:4|0|0|0|0|1|0|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4 - {0x0fe00010, 0x00800000, 2, arm_ADD_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}}, // ADD{S} ,,{,} cond:4|0|0|0|0|1|0|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4 - {0x0fef0000, 0x028d0000, 2, arm_ADD_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_SP, arm_arg_const}}, // ADD{S} ,SP,# cond:4|0|0|1|0|1|0|0|S|1|1|0|1|Rd:4|imm12:12 - {0x0fef0010, 0x008d0000, 2, arm_ADD_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_SP, arm_arg_R_shift_imm}}, // ADD{S} ,SP,{,} cond:4|0|0|0|0|1|0|0|S|1|1|0|1|Rd:4|imm5:5|type:2|0|Rm:4 - {0x0fe00000, 0x02000000, 2, arm_AND_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}}, // AND{S} ,,# cond:4|0|0|1|0|0|0|0|S|Rn:4|Rd:4|imm12:12 - {0x0fe00090, 0x00000010, 4, arm_AND_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}}, // AND{S} ,,, cond:4|0|0|0|0|0|0|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4 - {0x0fe00010, 0x00000000, 2, arm_AND_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}}, // AND{S} ,,{,} cond:4|0|0|0|0|0|0|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4 - {0x0fef0070, 0x01a00040, 4, arm_ASR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_imm5_32}}, // ASR{S} ,,# cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|imm5:5|1|0|0|Rm:4 - {0x0fef00f0, 0x01a00050, 4, arm_ASR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_R_8}}, // ASR{S} ,, cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|Rm:4|0|1|0|1|Rn:4 - {0x0f000000, 0x0a000000, 4, arm_B_EQ, 0x1c04, arm_instArgs{arm_arg_label24}}, // B cond:4|1|0|1|0|imm24:24 - {0x0fe0007f, 0x07c0001f, 4, arm_BFC_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_imm5, arm_arg_lsb_width}}, // BFC ,#,# cond:4|0|1|1|1|1|1|0|msb:5|Rd:4|lsb:5|0|0|1|1|1|1|1 - {0x0fe00070, 0x07c00010, 2, arm_BFI_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_imm5, arm_arg_lsb_width}}, // BFI ,,#,# cond:4|0|1|1|1|1|1|0|msb:5|Rd:4|lsb:5|0|0|1|Rn:4 - {0x0fe00000, 0x03c00000, 2, arm_BIC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}}, // BIC{S} ,,# cond:4|0|0|1|1|1|1|0|S|Rn:4|Rd:4|imm12:12 - {0x0fe00090, 0x01c00010, 4, arm_BIC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}}, // BIC{S} ,,, cond:4|0|0|0|1|1|1|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4 - {0x0fe00010, 0x01c00000, 2, arm_BIC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}}, // BIC{S} ,,{,} cond:4|0|0|0|1|1|1|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4 - {0x0ff000f0, 0x01200070, 4, arm_BKPT_EQ, 0x1c04, arm_instArgs{arm_arg_imm_12at8_4at0}}, // BKPT # cond:4|0|0|0|1|0|0|1|0|imm12:12|0|1|1|1|imm4:4 - {0x0f000000, 0x0b000000, 4, arm_BL_EQ, 0x1c04, arm_instArgs{arm_arg_label24}}, // BL cond:4|1|0|1|1|imm24:24 - {0xfe000000, 0xfa000000, 4, arm_BLX, 0x0, arm_instArgs{arm_arg_label24H}}, // BLX 1|1|1|1|1|0|1|H|imm24:24 - {0x0ffffff0, 0x012fff30, 4, arm_BLX_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}}, // BLX cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4 - {0x0ff000f0, 0x012fff30, 3, arm_BLX_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}}, // BLX cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4 - {0x0ffffff0, 0x012fff10, 4, arm_BX_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}}, // BX cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4 - {0x0ff000f0, 0x012fff10, 3, arm_BX_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}}, // BX cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4 - {0x0ffffff0, 0x012fff20, 4, arm_BXJ_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}}, // BXJ cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|1|0|Rm:4 - {0x0ff000f0, 0x012fff20, 3, arm_BXJ_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}}, // BXJ cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|1|0|Rm:4 - {0xffffffff, 0xf57ff01f, 4, arm_CLREX, 0x0, arm_instArgs{}}, // CLREX 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|1|(1)|(1)|(1)|(1) - {0xfff000f0, 0xf57ff01f, 3, arm_CLREX, 0x0, arm_instArgs{}}, // CLREX 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|1|(1)|(1)|(1)|(1) - {0x0fff0ff0, 0x016f0f10, 4, arm_CLZ_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}}, // CLZ , cond:4|0|0|0|1|0|1|1|0|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4 - {0x0ff000f0, 0x016f0f10, 3, arm_CLZ_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}}, // CLZ , cond:4|0|0|0|1|0|1|1|0|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4 - {0x0ff0f000, 0x03700000, 4, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}}, // CMN ,# cond:4|0|0|1|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12 - {0x0ff00000, 0x03700000, 3, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}}, // CMN ,# cond:4|0|0|1|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12 - {0x0ff0f090, 0x01700010, 4, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}}, // CMN ,, cond:4|0|0|0|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4 - {0x0ff00090, 0x01700010, 3, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}}, // CMN ,, cond:4|0|0|0|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4 - {0x0ff0f010, 0x01700000, 4, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}}, // CMN ,{,} cond:4|0|0|0|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4 - {0x0ff00010, 0x01700000, 3, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}}, // CMN ,{,} cond:4|0|0|0|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4 - {0x0ff0f000, 0x03500000, 4, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}}, // CMP ,# cond:4|0|0|1|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12 - {0x0ff00000, 0x03500000, 3, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}}, // CMP ,# cond:4|0|0|1|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12 - {0x0ff0f090, 0x01500010, 4, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}}, // CMP ,, cond:4|0|0|0|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4 - {0x0ff00090, 0x01500010, 3, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}}, // CMP ,, cond:4|0|0|0|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4 - {0x0ff0f010, 0x01500000, 4, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}}, // CMP ,{,} cond:4|0|0|0|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4 - {0x0ff00010, 0x01500000, 3, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}}, // CMP ,{,} cond:4|0|0|0|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4 - {0x0ffffff0, 0x0320f0f0, 4, arm_DBG_EQ, 0x1c04, arm_instArgs{arm_arg_option}}, // DBG #