diff options
author | Wim <wim@42.be> | 2017-03-23 23:28:55 +0100 |
---|---|---|
committer | Wim <wim@42.be> | 2017-03-23 23:28:55 +0100 |
commit | 2f68519b3c6b5a70028882c99afeb76f291b7725 (patch) | |
tree | 2555d0b8b81491f136a176a58e2618a25edc8edc /vendor/golang.org/x/arch/arm/armasm/inst.go | |
parent | efe641f202653dfd3bc7bde221188e098db3def7 (diff) | |
download | matterbridge-msglm-2f68519b3c6b5a70028882c99afeb76f291b7725.tar.gz matterbridge-msglm-2f68519b3c6b5a70028882c99afeb76f291b7725.tar.bz2 matterbridge-msglm-2f68519b3c6b5a70028882c99afeb76f291b7725.zip |
Add gops agentv0.10.2-dev
Diffstat (limited to 'vendor/golang.org/x/arch/arm/armasm/inst.go')
-rw-r--r-- | vendor/golang.org/x/arch/arm/armasm/inst.go | 438 |
1 files changed, 438 insertions, 0 deletions
diff --git a/vendor/golang.org/x/arch/arm/armasm/inst.go b/vendor/golang.org/x/arch/arm/armasm/inst.go new file mode 100644 index 00000000..60d633bd --- /dev/null +++ b/vendor/golang.org/x/arch/arm/armasm/inst.go @@ -0,0 +1,438 @@ +// 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 armasm + +import ( + "bytes" + "fmt" +) + +// A Mode is an instruction execution mode. +type Mode int + +const ( + _ Mode = iota + ModeARM + ModeThumb +) + +func (m Mode) String() string { + switch m { + case ModeARM: + return "ARM" + case ModeThumb: + return "Thumb" + } + return fmt.Sprintf("Mode(%d)", int(m)) +} + +// An Op is an ARM opcode. +type Op uint16 + +// NOTE: The actual Op values are defined in tables.go. +// They are chosen to simplify instruction decoding and +// are not a dense packing from 0 to N, although the +// density is high, probably at least 90%. + +func (op Op) String() string { + if op >= Op(len(opstr)) || opstr[op] == "" { + return fmt.Sprintf("Op(%d)", int(op)) + } + return opstr[op] +} + +// An Inst is a single instruction. +type Inst struct { + Op Op // Opcode mnemonic + Enc uint32 // Raw encoding bits. + Len int // Length of encoding in bytes. + Args Args // Instruction arguments, in ARM manual order. +} + +func (i 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 Args [4]Arg + +// An Arg is a single instruction argument, one of these types: +// Endian, Imm, Mem, PCRel, Reg, RegList, RegShift, RegShiftReg. +type Arg interface { + IsArg() + String() string +} + +type Float32Imm float32 + +func (Float32Imm) IsArg() {} + +func (f Float32Imm) String() string { + return fmt.Sprintf("#%v", float32(f)) +} + +type Float64Imm float32 + +func (Float64Imm) IsArg() {} + +func (f Float64Imm) String() string { + return fmt.Sprintf("#%v", float64(f)) +} + +// An Imm is an integer constant. +type Imm uint32 + +func (Imm) IsArg() {} + +func (i Imm) String() string { + return fmt.Sprintf("#%#x", uint32(i)) +} + +// A ImmAlt is an alternate encoding of an integer constant. +type ImmAlt struct { + Val uint8 + Rot uint8 +} + +func (ImmAlt) IsArg() {} + +func (i ImmAlt) Imm() Imm { + v := uint32(i.Val) + r := uint(i.Rot) + return Imm(v>>r | v<<(32-r)) +} + +func (i ImmAlt) String() string { + return fmt.Sprintf("#%#x, %d", i.Val, i.Rot) +} + +// A Label is a text (code) address. +type Label uint32 + +func (Label) IsArg() {} + +func (i 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 Reg uint8 + +const ( + R0 Reg = iota + R1 + R2 + R3 + R4 + R5 + R6 + R7 + R8 + R9 + R10 + R11 + R12 + R13 + R14 + R15 + + S0 + S1 + S2 + S3 + S4 + S5 + S6 + S7 + S8 + S9 + S10 + S11 + S12 + S13 + S14 + S15 + S16 + S17 + S18 + S19 + S20 + S21 + S22 + S23 + S24 + S25 + S26 + S27 + S28 + S29 + S30 + S31 + + D0 + D1 + D2 + D3 + D4 + D5 + D6 + D7 + D8 + D9 + D10 + D11 + D12 + D13 + D14 + D15 + D16 + D17 + D18 + D19 + D20 + D21 + D22 + D23 + D24 + D25 + D26 + D27 + D28 + D29 + D30 + D31 + + APSR + APSR_nzcv + FPSCR + + SP = R13 + LR = R14 + PC = R15 +) + +func (Reg) IsArg() {} + +func (r Reg) String() string { + switch r { + case APSR: + return "APSR" + case APSR_nzcv: + return "APSR_nzcv" + case FPSCR: + return "FPSCR" + case SP: + return "SP" + case PC: + return "PC" + case LR: + return "LR" + } + if R0 <= r && r <= R15 { + return fmt.Sprintf("R%d", int(r-R0)) + } + if S0 <= r && r <= S31 { + return fmt.Sprintf("S%d", int(r-S0)) + } + if D0 <= r && r <= D31 { + return fmt.Sprintf("D%d", int(r-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 RegX struct { + Reg Reg + Index int +} + +func (RegX) IsArg() {} + +func (r 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 RegList uint16 + +func (RegList) IsArg() {} + +func (r RegList) String() string { + var buf bytes.Buffer + fmt.Fprintf(&buf, "{") + sep := "" + for i := 0; i < 16; i++ { + if r&(1<<uint(i)) != 0 { + fmt.Fprintf(&buf, "%s%s", sep, Reg(i).String()) + sep = "," + } + } + fmt.Fprintf(&buf, "}") + return buf.String() +} + +// An Endian is the argument to the SETEND instruction. +type Endian uint8 + +const ( + LittleEndian Endian = 0 + BigEndian Endian = 1 +) + +func (Endian) IsArg() {} + +func (e Endian) String() string { + if e != 0 { + return "BE" + } + return "LE" +} + +// A Shift describes an ARM shift operation. +type Shift uint8 + +const ( + ShiftLeft Shift = 0 // left shift + ShiftRight Shift = 1 // logical (unsigned) right shift + ShiftRightSigned Shift = 2 // arithmetic (signed) right shift + RotateRight Shift = 3 // right rotate + RotateRightExt Shift = 4 // right rotate through carry (Count will always be 1) +) + +var shiftName = [...]string{ + "LSL", "LSR", "ASR", "ROR", "RRX", +} + +func (s Shift) String() string { + if s < 5 { + return shiftName[s] + } + return fmt.Sprintf("Shift(%d)", int(s)) +} + +// A RegShift is a register shifted by a constant. +type RegShift struct { + Reg Reg + Shift Shift + Count uint8 +} + +func (RegShift) IsArg() {} + +func (r RegShift) String() string { + return fmt.Sprintf("%s %s #%d", r.Reg, r.Shift, r.Count) +} + +// A RegShiftReg is a register shifted by a register. +type RegShiftReg struct { + Reg Reg + Shift Shift + RegCount Reg +} + +func (RegShiftReg) IsArg() {} + +func (r RegShiftReg) String() string { + return fmt.Sprintf("%s %s %s", r.Reg, r.Shift, r.RegCount) +} + +// A PCRel describes a memory address (usually a code label) +// as a distance relative to the program counter. +// TODO(rsc): Define which program counter (PC+4? PC+8? PC?). +type PCRel int32 + +func (PCRel) IsArg() {} + +func (r PCRel) String() string { + return fmt.Sprintf("PC%+#x", int32(r)) +} + +// An AddrMode is an ARM addressing mode. +type AddrMode uint8 + +const ( + _ AddrMode = iota + AddrPostIndex // [R], X – use address R, set R = R + X + AddrPreIndex // [R, X]! – use address R + X, set R = R + X + AddrOffset // [R, X] – use address R + X + AddrLDM // R – [R] but formats as R, for LDM/STM only + AddrLDM_WB // R! - [R], X where X is instruction-specific amount, for LDM/STM only +) + +// A Mem is a memory reference made up of a base R and index expression X. +// The effective memory address is R or R+X depending on AddrMode. +// The index expression is X = Sign*(Index Shift Count) + Offset, +// but in any instruction either Sign = 0 or Offset = 0. +type Mem struct { + Base Reg + Mode AddrMode + Sign int8 + Index Reg + Shift Shift + Count uint8 + Offset int16 +} + +func (Mem) IsArg() {} + +func (m Mem) String() string { + R := m.Base.String() + X := "" + if m.Sign != 0 { + X = "+" + if m.Sign < 0 { + X = "-" + } + X += m.Index.String() + if m.Shift != ShiftLeft || m.Count != 0 { + X += fmt.Sprintf(", %s #%d", m.Shift, m.Count) + } + } else { + X = fmt.Sprintf("#%d", m.Offset) + } + + switch m.Mode { + case AddrOffset: + if X == "#0" { + return fmt.Sprintf("[%s]", R) + } + return fmt.Sprintf("[%s, %s]", R, X) + case AddrPreIndex: + return fmt.Sprintf("[%s, %s]!", R, X) + case AddrPostIndex: + return fmt.Sprintf("[%s], %s", R, X) + case AddrLDM: + if X == "#0" { + return R + } + case AddrLDM_WB: + if X == "#0" { + return R + "!" + } + } + return fmt.Sprintf("[%s Mode(%d) %s]", R, int(m.Mode), X) +} |