...

Source file src/pkg/cmd/vendor/golang.org/x/arch/arm/armasm/gnu.go

     1	// Copyright 2014 The Go Authors.  All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	package armasm
     6	
     7	import (
     8		"bytes"
     9		"fmt"
    10		"strings"
    11	)
    12	
    13	var saveDot = strings.NewReplacer(
    14		".F16", "_dot_F16",
    15		".F32", "_dot_F32",
    16		".F64", "_dot_F64",
    17		".S32", "_dot_S32",
    18		".U32", "_dot_U32",
    19		".FXS", "_dot_S",
    20		".FXU", "_dot_U",
    21		".32", "_dot_32",
    22	)
    23	
    24	// GNUSyntax returns the GNU assembler syntax for the instruction, as defined by GNU binutils.
    25	// This form typically matches the syntax defined in the ARM Reference Manual.
    26	func GNUSyntax(inst Inst) string {
    27		var buf bytes.Buffer
    28		op := inst.Op.String()
    29		op = saveDot.Replace(op)
    30		op = strings.Replace(op, ".", "", -1)
    31		op = strings.Replace(op, "_dot_", ".", -1)
    32		op = strings.ToLower(op)
    33		buf.WriteString(op)
    34		sep := " "
    35		for i, arg := range inst.Args {
    36			if arg == nil {
    37				break
    38			}
    39			text := gnuArg(&inst, i, arg)
    40			if text == "" {
    41				continue
    42			}
    43			buf.WriteString(sep)
    44			sep = ", "
    45			buf.WriteString(text)
    46		}
    47		return buf.String()
    48	}
    49	
    50	func gnuArg(inst *Inst, argIndex int, arg Arg) string {
    51		switch inst.Op &^ 15 {
    52		case LDRD_EQ, LDREXD_EQ, STRD_EQ:
    53			if argIndex == 1 {
    54				// second argument in consecutive pair not printed
    55				return ""
    56			}
    57		case STREXD_EQ:
    58			if argIndex == 2 {
    59				// second argument in consecutive pair not printed
    60				return ""
    61			}
    62		}
    63	
    64		switch arg := arg.(type) {
    65		case Imm:
    66			switch inst.Op &^ 15 {
    67			case BKPT_EQ:
    68				return fmt.Sprintf("%#04x", uint32(arg))
    69			case SVC_EQ:
    70				return fmt.Sprintf("%#08x", uint32(arg))
    71			}
    72			return fmt.Sprintf("#%d", int32(arg))
    73	
    74		case ImmAlt:
    75			return fmt.Sprintf("#%d, %d", arg.Val, arg.Rot)
    76	
    77		case Mem:
    78			R := gnuArg(inst, -1, arg.Base)
    79			X := ""
    80			if arg.Sign != 0 {
    81				X = ""
    82				if arg.Sign < 0 {
    83					X = "-"
    84				}
    85				X += gnuArg(inst, -1, arg.Index)
    86				if arg.Shift == ShiftLeft && arg.Count == 0 {
    87					// nothing
    88				} else if arg.Shift == RotateRightExt {
    89					X += ", rrx"
    90				} else {
    91					X += fmt.Sprintf(", %s #%d", strings.ToLower(arg.Shift.String()), arg.Count)
    92				}
    93			} else {
    94				X = fmt.Sprintf("#%d", arg.Offset)
    95			}
    96	
    97			switch arg.Mode {
    98			case AddrOffset:
    99				if X == "#0" {
   100					return fmt.Sprintf("[%s]", R)
   101				}
   102				return fmt.Sprintf("[%s, %s]", R, X)
   103			case AddrPreIndex:
   104				return fmt.Sprintf("[%s, %s]!", R, X)
   105			case AddrPostIndex:
   106				return fmt.Sprintf("[%s], %s", R, X)
   107			case AddrLDM:
   108				if X == "#0" {
   109					return R
   110				}
   111			case AddrLDM_WB:
   112				if X == "#0" {
   113					return R + "!"
   114				}
   115			}
   116			return fmt.Sprintf("[%s Mode(%d) %s]", R, int(arg.Mode), X)
   117	
   118		case PCRel:
   119			return fmt.Sprintf(".%+#x", int32(arg)+4)
   120	
   121		case Reg:
   122			switch inst.Op &^ 15 {
   123			case LDREX_EQ:
   124				if argIndex == 0 {
   125					return fmt.Sprintf("r%d", int32(arg))
   126				}
   127			}
   128			switch arg {
   129			case R10:
   130				return "sl"
   131			case R11:
   132				return "fp"
   133			case R12:
   134				return "ip"
   135			}
   136	
   137		case RegList:
   138			var buf bytes.Buffer
   139			fmt.Fprintf(&buf, "{")
   140			sep := ""
   141			for i := 0; i < 16; i++ {
   142				if arg&(1<<uint(i)) != 0 {
   143					fmt.Fprintf(&buf, "%s%s", sep, gnuArg(inst, -1, Reg(i)))
   144					sep = ", "
   145				}
   146			}
   147			fmt.Fprintf(&buf, "}")
   148			return buf.String()
   149	
   150		case RegShift:
   151			if arg.Shift == ShiftLeft && arg.Count == 0 {
   152				return gnuArg(inst, -1, arg.Reg)
   153			}
   154			if arg.Shift == RotateRightExt {
   155				return gnuArg(inst, -1, arg.Reg) + ", rrx"
   156			}
   157			return fmt.Sprintf("%s, %s #%d", gnuArg(inst, -1, arg.Reg), strings.ToLower(arg.Shift.String()), arg.Count)
   158	
   159		case RegShiftReg:
   160			return fmt.Sprintf("%s, %s %s", gnuArg(inst, -1, arg.Reg), strings.ToLower(arg.Shift.String()), gnuArg(inst, -1, arg.RegCount))
   161	
   162		}
   163		return strings.ToLower(arg.String())
   164	}
   165	

View as plain text