Source file src/pkg/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/gnu.go
1
2
3
4
5 package ppc64asm
6
7 import (
8 "bytes"
9 "fmt"
10 "strings"
11 )
12
13
14
15 func GNUSyntax(inst Inst) string {
16 var buf bytes.Buffer
17
18
19 if inst.Enc == 0 {
20 return ".long 0x0"
21 } else if inst.Op == 0 {
22 return "error: unknown instruction"
23 }
24 buf.WriteString(inst.Op.String())
25 sep := " "
26 for i, arg := range inst.Args[:] {
27 if arg == nil {
28 break
29 }
30 text := gnuArg(&inst, i, arg)
31 if text == "" {
32 continue
33 }
34 buf.WriteString(sep)
35 sep = ","
36 buf.WriteString(text)
37 }
38 return buf.String()
39 }
40
41
42
43
44 func gnuArg(inst *Inst, argIndex int, arg Arg) string {
45
46 if _, ok := arg.(Offset); ok {
47 if argIndex+1 == len(inst.Args) || inst.Args[argIndex+1] == nil {
48 panic(fmt.Errorf("wrong table: offset not followed by register"))
49 }
50 }
51 switch arg := arg.(type) {
52 case Reg:
53 if isLoadStoreOp(inst.Op) && argIndex == 1 && arg == R0 {
54 return "0"
55 }
56 return arg.String()
57 case CondReg:
58 if arg == CR0 && strings.HasPrefix(inst.Op.String(), "cmp") {
59 return ""
60 } else if arg >= CR0 {
61 return fmt.Sprintf("cr%d", int(arg-CR0))
62 }
63 bit := [4]string{"lt", "gt", "eq", "so"}[(arg-Cond0LT)%4]
64 if arg <= Cond0SO {
65 return bit
66 }
67 return fmt.Sprintf("4*cr%d+%s", int(arg-Cond0LT)/4, bit)
68 case Imm:
69 return fmt.Sprintf("%d", arg)
70 case SpReg:
71 return fmt.Sprintf("%d", int(arg))
72 case PCRel:
73 return fmt.Sprintf(".%+#x", int(arg))
74 case Label:
75 return fmt.Sprintf("%#x", uint32(arg))
76 case Offset:
77 reg := inst.Args[argIndex+1].(Reg)
78 removeArg(inst, argIndex+1)
79 if reg == R0 {
80 return fmt.Sprintf("%d(0)", int(arg))
81 }
82 return fmt.Sprintf("%d(r%d)", int(arg), reg-R0)
83 }
84 return fmt.Sprintf("???(%v)", arg)
85 }
86
87
88 func removeArg(inst *Inst, index int) {
89 for i := index; i < len(inst.Args); i++ {
90 if i+1 < len(inst.Args) {
91 inst.Args[i] = inst.Args[i+1]
92 } else {
93 inst.Args[i] = nil
94 }
95 }
96 }
97
98
99 func isLoadStoreOp(op Op) bool {
100 switch op {
101 case LBZ, LBZU, LBZX, LBZUX:
102 return true
103 case LHZ, LHZU, LHZX, LHZUX:
104 return true
105 case LHA, LHAU, LHAX, LHAUX:
106 return true
107 case LWZ, LWZU, LWZX, LWZUX:
108 return true
109 case LWA, LWAX, LWAUX:
110 return true
111 case LD, LDU, LDX, LDUX:
112 return true
113 case LQ:
114 return true
115 case STB, STBU, STBX, STBUX:
116 return true
117 case STH, STHU, STHX, STHUX:
118 return true
119 case STW, STWU, STWX, STWUX:
120 return true
121 case STD, STDU, STDX, STDUX:
122 return true
123 case STQ:
124 return true
125 case LHBRX, LWBRX, STHBRX, STWBRX:
126 return true
127 }
128 return false
129 }
130
View as plain text