]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/internal/obj/ppc64/asm9.go
f786f3c4434df3d1583e8183f7138665660300c8
[gostls13.git] / src / cmd / internal / obj / ppc64 / asm9.go
1 // cmd/9l/optab.c, cmd/9l/asmout.c from Vita Nuova.
2 //
3 //      Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
4 //      Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
5 //      Portions Copyright © 1997-1999 Vita Nuova Limited
6 //      Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
7 //      Portions Copyright © 2004,2006 Bruce Ellis
8 //      Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
9 //      Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
10 //      Portions Copyright © 2009 The Go Authors.  All rights reserved.
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining a copy
13 // of this software and associated documentation files (the "Software"), to deal
14 // in the Software without restriction, including without limitation the rights
15 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 // copies of the Software, and to permit persons to whom the Software is
17 // furnished to do so, subject to the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be included in
20 // all copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
25 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 // THE SOFTWARE.
29
30 package ppc64
31
32 import (
33         "cmd/internal/obj"
34         "encoding/binary"
35         "fmt"
36         "log"
37         "sort"
38 )
39
40 // Instruction layout.
41
42 const (
43         FuncAlign = 8
44 )
45
46 const (
47         r0iszero = 1
48 )
49
50 type Optab struct {
51         as    obj.As
52         a1    uint8
53         a2    uint8
54         a3    uint8
55         a4    uint8
56         type_ int8
57         size  int8
58         param int16
59 }
60
61 var optab = []Optab{
62         {obj.ATEXT, C_LEXT, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0},
63         {obj.ATEXT, C_LEXT, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0},
64         {obj.ATEXT, C_ADDR, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0},
65         {obj.ATEXT, C_ADDR, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0},
66         /* move register */
67         {AMOVD, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0},
68         {AMOVB, C_REG, C_NONE, C_NONE, C_REG, 12, 4, 0},
69         {AMOVBZ, C_REG, C_NONE, C_NONE, C_REG, 13, 4, 0},
70         {AMOVW, C_REG, C_NONE, C_NONE, C_REG, 12, 4, 0},
71         {AMOVWZ, C_REG, C_NONE, C_NONE, C_REG, 13, 4, 0},
72         {AADD, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0},
73         {AADD, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
74         {AADD, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
75         {AADD, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
76         {AADD, C_UCON, C_REG, C_NONE, C_REG, 20, 4, 0},
77         {AADD, C_UCON, C_NONE, C_NONE, C_REG, 20, 4, 0},
78         {AADD, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0},
79         {AADD, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0},
80         {AADDC, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0},
81         {AADDC, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
82         {AADDC, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
83         {AADDC, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
84         {AADDC, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0},
85         {AADDC, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0},
86         {AAND, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, /* logical, no literal */
87         {AAND, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
88         {AANDCC, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
89         {AANDCC, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
90         {AANDCC, C_ANDCON, C_NONE, C_NONE, C_REG, 58, 4, 0},
91         {AANDCC, C_ANDCON, C_REG, C_NONE, C_REG, 58, 4, 0},
92         {AANDCC, C_UCON, C_NONE, C_NONE, C_REG, 59, 4, 0},
93         {AANDCC, C_UCON, C_REG, C_NONE, C_REG, 59, 4, 0},
94         {AANDCC, C_LCON, C_NONE, C_NONE, C_REG, 23, 12, 0},
95         {AANDCC, C_LCON, C_REG, C_NONE, C_REG, 23, 12, 0},
96         {AMULLW, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0},
97         {AMULLW, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
98         {AMULLW, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
99         {AMULLW, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
100         {AMULLW, C_ANDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
101         {AMULLW, C_ANDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
102         {AMULLW, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0},
103         {AMULLW, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0},
104         {ASUBC, C_REG, C_REG, C_NONE, C_REG, 10, 4, 0},
105         {ASUBC, C_REG, C_NONE, C_NONE, C_REG, 10, 4, 0},
106         {ASUBC, C_REG, C_NONE, C_ADDCON, C_REG, 27, 4, 0},
107         {ASUBC, C_REG, C_NONE, C_LCON, C_REG, 28, 12, 0},
108         {AOR, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, /* logical, literal not cc (or/xor) */
109         {AOR, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
110         {AOR, C_ANDCON, C_NONE, C_NONE, C_REG, 58, 4, 0},
111         {AOR, C_ANDCON, C_REG, C_NONE, C_REG, 58, 4, 0},
112         {AOR, C_UCON, C_NONE, C_NONE, C_REG, 59, 4, 0},
113         {AOR, C_UCON, C_REG, C_NONE, C_REG, 59, 4, 0},
114         {AOR, C_LCON, C_NONE, C_NONE, C_REG, 23, 12, 0},
115         {AOR, C_LCON, C_REG, C_NONE, C_REG, 23, 12, 0},
116         {ADIVW, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0}, /* op r1[,r2],r3 */
117         {ADIVW, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
118         {ASUB, C_REG, C_REG, C_NONE, C_REG, 10, 4, 0}, /* op r2[,r1],r3 */
119         {ASUB, C_REG, C_NONE, C_NONE, C_REG, 10, 4, 0},
120         {ASLW, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
121         {ASLW, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
122         {ASLD, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
123         {ASLD, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
124         {ASLD, C_SCON, C_REG, C_NONE, C_REG, 25, 4, 0},
125         {ASLD, C_SCON, C_NONE, C_NONE, C_REG, 25, 4, 0},
126         {ASLW, C_SCON, C_REG, C_NONE, C_REG, 57, 4, 0},
127         {ASLW, C_SCON, C_NONE, C_NONE, C_REG, 57, 4, 0},
128         {ASRAW, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
129         {ASRAW, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
130         {ASRAW, C_SCON, C_REG, C_NONE, C_REG, 56, 4, 0},
131         {ASRAW, C_SCON, C_NONE, C_NONE, C_REG, 56, 4, 0},
132         {ASRAD, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
133         {ASRAD, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
134         {ASRAD, C_SCON, C_REG, C_NONE, C_REG, 56, 4, 0},
135         {ASRAD, C_SCON, C_NONE, C_NONE, C_REG, 56, 4, 0},
136         {ARLWMI, C_SCON, C_REG, C_LCON, C_REG, 62, 4, 0},
137         {ARLWMI, C_REG, C_REG, C_LCON, C_REG, 63, 4, 0},
138         {ARLDMI, C_SCON, C_REG, C_LCON, C_REG, 30, 4, 0},
139         {ARLDC, C_SCON, C_REG, C_LCON, C_REG, 29, 4, 0},
140         {ARLDCL, C_SCON, C_REG, C_LCON, C_REG, 29, 4, 0},
141         {ARLDCL, C_REG, C_REG, C_LCON, C_REG, 14, 4, 0},
142         {ARLDCL, C_REG, C_NONE, C_LCON, C_REG, 14, 4, 0},
143         {AFADD, C_FREG, C_NONE, C_NONE, C_FREG, 2, 4, 0},
144         {AFADD, C_FREG, C_REG, C_NONE, C_FREG, 2, 4, 0},
145         {AFABS, C_FREG, C_NONE, C_NONE, C_FREG, 33, 4, 0},
146         {AFABS, C_NONE, C_NONE, C_NONE, C_FREG, 33, 4, 0},
147         {AFMOVD, C_FREG, C_NONE, C_NONE, C_FREG, 33, 4, 0},
148         {AFMADD, C_FREG, C_REG, C_FREG, C_FREG, 34, 4, 0},
149         {AFMUL, C_FREG, C_NONE, C_NONE, C_FREG, 32, 4, 0},
150         {AFMUL, C_FREG, C_REG, C_NONE, C_FREG, 32, 4, 0},
151
152         /* store, short offset */
153         {AMOVD, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
154         {AMOVW, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
155         {AMOVWZ, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
156         {AMOVBZ, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
157         {AMOVBZU, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
158         {AMOVB, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
159         {AMOVBU, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
160         {AMOVD, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
161         {AMOVW, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
162         {AMOVWZ, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
163         {AMOVBZ, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
164         {AMOVB, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
165         {AMOVD, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
166         {AMOVW, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
167         {AMOVWZ, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
168         {AMOVBZ, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
169         {AMOVB, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
170         {AMOVD, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
171         {AMOVW, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
172         {AMOVWZ, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
173         {AMOVBZ, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
174         {AMOVBZU, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
175         {AMOVB, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
176         {AMOVBU, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
177
178         /* load, short offset */
179         {AMOVD, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
180         {AMOVW, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
181         {AMOVWZ, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
182         {AMOVBZ, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
183         {AMOVBZU, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
184         {AMOVB, C_ZOREG, C_REG, C_NONE, C_REG, 9, 8, REGZERO},
185         {AMOVBU, C_ZOREG, C_REG, C_NONE, C_REG, 9, 8, REGZERO},
186         {AMOVD, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
187         {AMOVW, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
188         {AMOVWZ, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
189         {AMOVBZ, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
190         {AMOVB, C_SEXT, C_NONE, C_NONE, C_REG, 9, 8, REGSB},
191         {AMOVD, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
192         {AMOVW, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
193         {AMOVWZ, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
194         {AMOVBZ, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
195         {AMOVB, C_SAUTO, C_NONE, C_NONE, C_REG, 9, 8, REGSP},
196         {AMOVD, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
197         {AMOVW, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
198         {AMOVWZ, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
199         {AMOVBZ, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
200         {AMOVBZU, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
201         {AMOVB, C_SOREG, C_NONE, C_NONE, C_REG, 9, 8, REGZERO},
202         {AMOVBU, C_SOREG, C_NONE, C_NONE, C_REG, 9, 8, REGZERO},
203
204         /* store, long offset */
205         {AMOVD, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
206         {AMOVW, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
207         {AMOVWZ, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
208         {AMOVBZ, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
209         {AMOVB, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
210         {AMOVD, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
211         {AMOVW, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
212         {AMOVWZ, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
213         {AMOVBZ, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
214         {AMOVB, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
215         {AMOVD, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
216         {AMOVW, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
217         {AMOVWZ, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
218         {AMOVBZ, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
219         {AMOVB, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
220         {AMOVD, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
221         {AMOVW, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
222         {AMOVWZ, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
223         {AMOVBZ, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
224         {AMOVB, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
225
226         /* load, long offset */
227         {AMOVD, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
228         {AMOVW, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
229         {AMOVWZ, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
230         {AMOVBZ, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
231         {AMOVB, C_LEXT, C_NONE, C_NONE, C_REG, 37, 12, REGSB},
232         {AMOVD, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
233         {AMOVW, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
234         {AMOVWZ, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
235         {AMOVBZ, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
236         {AMOVB, C_LAUTO, C_NONE, C_NONE, C_REG, 37, 12, REGSP},
237         {AMOVD, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
238         {AMOVW, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
239         {AMOVWZ, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
240         {AMOVBZ, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
241         {AMOVB, C_LOREG, C_NONE, C_NONE, C_REG, 37, 12, REGZERO},
242         {AMOVD, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
243         {AMOVW, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
244         {AMOVWZ, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
245         {AMOVBZ, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
246         {AMOVB, C_ADDR, C_NONE, C_NONE, C_REG, 76, 12, 0},
247
248         {AMOVD, C_TLS_LE, C_NONE, C_NONE, C_REG, 79, 4, 0},
249         {AMOVD, C_TLS_IE, C_NONE, C_NONE, C_REG, 80, 8, 0},
250
251         {AMOVD, C_GOTADDR, C_NONE, C_NONE, C_REG, 81, 8, 0},
252
253         /* load constant */
254         {AMOVD, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB},
255         {AMOVD, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP},
256         {AMOVD, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB},
257         {AMOVD, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP},
258         {AMOVD, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
259         {AMOVW, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB}, /* TO DO: check */
260         {AMOVW, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP},
261         {AMOVW, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB},
262         {AMOVW, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP},
263         {AMOVW, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
264         {AMOVWZ, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB}, /* TO DO: check */
265         {AMOVWZ, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP},
266         {AMOVWZ, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB},
267         {AMOVWZ, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP},
268         {AMOVWZ, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
269
270         /* load unsigned/long constants (TO DO: check) */
271         {AMOVD, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
272         {AMOVD, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0},
273         {AMOVW, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
274         {AMOVW, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0},
275         {AMOVWZ, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
276         {AMOVWZ, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0},
277         {AMOVHBR, C_ZOREG, C_REG, C_NONE, C_REG, 45, 4, 0},
278         {AMOVHBR, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
279         {AMOVHBR, C_REG, C_REG, C_NONE, C_ZOREG, 44, 4, 0},
280         {AMOVHBR, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
281         {ASYSCALL, C_NONE, C_NONE, C_NONE, C_NONE, 5, 4, 0},
282         {ASYSCALL, C_REG, C_NONE, C_NONE, C_NONE, 77, 12, 0},
283         {ASYSCALL, C_SCON, C_NONE, C_NONE, C_NONE, 77, 12, 0},
284         {ABEQ, C_NONE, C_NONE, C_NONE, C_SBRA, 16, 4, 0},
285         {ABEQ, C_CREG, C_NONE, C_NONE, C_SBRA, 16, 4, 0},
286         {ABR, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0},
287         {ABR, C_NONE, C_NONE, C_NONE, C_LBRAPIC, 11, 8, 0},
288         {ABC, C_SCON, C_REG, C_NONE, C_SBRA, 16, 4, 0},
289         {ABC, C_SCON, C_REG, C_NONE, C_LBRA, 17, 4, 0},
290         {ABR, C_NONE, C_NONE, C_NONE, C_LR, 18, 4, 0},
291         {ABR, C_NONE, C_NONE, C_NONE, C_CTR, 18, 4, 0},
292         {ABR, C_REG, C_NONE, C_NONE, C_CTR, 18, 4, 0},
293         {ABR, C_NONE, C_NONE, C_NONE, C_ZOREG, 15, 8, 0},
294         {ABC, C_NONE, C_REG, C_NONE, C_LR, 18, 4, 0},
295         {ABC, C_NONE, C_REG, C_NONE, C_CTR, 18, 4, 0},
296         {ABC, C_SCON, C_REG, C_NONE, C_LR, 18, 4, 0},
297         {ABC, C_SCON, C_REG, C_NONE, C_CTR, 18, 4, 0},
298         {ABC, C_NONE, C_NONE, C_NONE, C_ZOREG, 15, 8, 0},
299         {AFMOVD, C_SEXT, C_NONE, C_NONE, C_FREG, 8, 4, REGSB},
300         {AFMOVD, C_SAUTO, C_NONE, C_NONE, C_FREG, 8, 4, REGSP},
301         {AFMOVD, C_SOREG, C_NONE, C_NONE, C_FREG, 8, 4, REGZERO},
302         {AFMOVD, C_LEXT, C_NONE, C_NONE, C_FREG, 36, 8, REGSB},
303         {AFMOVD, C_LAUTO, C_NONE, C_NONE, C_FREG, 36, 8, REGSP},
304         {AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, 36, 8, REGZERO},
305         {AFMOVD, C_ADDR, C_NONE, C_NONE, C_FREG, 75, 8, 0},
306         {AFMOVD, C_FREG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
307         {AFMOVD, C_FREG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
308         {AFMOVD, C_FREG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
309         {AFMOVD, C_FREG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
310         {AFMOVD, C_FREG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
311         {AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
312         {AFMOVD, C_FREG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
313         {ASYNC, C_NONE, C_NONE, C_NONE, C_NONE, 46, 4, 0},
314         {AWORD, C_LCON, C_NONE, C_NONE, C_NONE, 40, 4, 0},
315         {ADWORD, C_LCON, C_NONE, C_NONE, C_NONE, 31, 8, 0},
316         {ADWORD, C_DCON, C_NONE, C_NONE, C_NONE, 31, 8, 0},
317         {AADDME, C_REG, C_NONE, C_NONE, C_REG, 47, 4, 0},
318         {AEXTSB, C_REG, C_NONE, C_NONE, C_REG, 48, 4, 0},
319         {AEXTSB, C_NONE, C_NONE, C_NONE, C_REG, 48, 4, 0},
320         {ANEG, C_REG, C_NONE, C_NONE, C_REG, 47, 4, 0},
321         {ANEG, C_NONE, C_NONE, C_NONE, C_REG, 47, 4, 0},
322         {AREM, C_REG, C_NONE, C_NONE, C_REG, 50, 12, 0},
323         {AREM, C_REG, C_REG, C_NONE, C_REG, 50, 12, 0},
324         {AREMU, C_REG, C_NONE, C_NONE, C_REG, 50, 16, 0},
325         {AREMU, C_REG, C_REG, C_NONE, C_REG, 50, 16, 0},
326         {AREMD, C_REG, C_NONE, C_NONE, C_REG, 51, 12, 0},
327         {AREMD, C_REG, C_REG, C_NONE, C_REG, 51, 12, 0},
328         {AREMDU, C_REG, C_NONE, C_NONE, C_REG, 51, 12, 0},
329         {AREMDU, C_REG, C_REG, C_NONE, C_REG, 51, 12, 0},
330         {AMTFSB0, C_SCON, C_NONE, C_NONE, C_NONE, 52, 4, 0},
331         {AMOVFL, C_FPSCR, C_NONE, C_NONE, C_FREG, 53, 4, 0},
332         {AMOVFL, C_FREG, C_NONE, C_NONE, C_FPSCR, 64, 4, 0},
333         {AMOVFL, C_FREG, C_NONE, C_LCON, C_FPSCR, 64, 4, 0},
334         {AMOVFL, C_LCON, C_NONE, C_NONE, C_FPSCR, 65, 4, 0},
335         {AMOVD, C_MSR, C_NONE, C_NONE, C_REG, 54, 4, 0},  /* mfmsr */
336         {AMOVD, C_REG, C_NONE, C_NONE, C_MSR, 54, 4, 0},  /* mtmsrd */
337         {AMOVWZ, C_REG, C_NONE, C_NONE, C_MSR, 54, 4, 0}, /* mtmsr */
338
339         /* 64-bit special registers */
340         {AMOVD, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},
341         {AMOVD, C_REG, C_NONE, C_NONE, C_LR, 66, 4, 0},
342         {AMOVD, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},
343         {AMOVD, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},
344         {AMOVD, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},
345         {AMOVD, C_LR, C_NONE, C_NONE, C_REG, 66, 4, 0},
346         {AMOVD, C_CTR, C_NONE, C_NONE, C_REG, 66, 4, 0},
347         {AMOVD, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},
348
349         /* 32-bit special registers (gloss over sign-extension or not?) */
350         {AMOVW, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},
351         {AMOVW, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},
352         {AMOVW, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},
353         {AMOVW, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},
354         {AMOVW, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},
355         {AMOVWZ, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},
356         {AMOVWZ, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},
357         {AMOVWZ, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},
358         {AMOVWZ, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},
359         {AMOVWZ, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},
360         {AMOVFL, C_FPSCR, C_NONE, C_NONE, C_CREG, 73, 4, 0},
361         {AMOVFL, C_CREG, C_NONE, C_NONE, C_CREG, 67, 4, 0},
362         {AMOVW, C_CREG, C_NONE, C_NONE, C_REG, 68, 4, 0},
363         {AMOVWZ, C_CREG, C_NONE, C_NONE, C_REG, 68, 4, 0},
364         {AMOVFL, C_REG, C_NONE, C_LCON, C_CREG, 69, 4, 0},
365         {AMOVFL, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},
366         {AMOVW, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},
367         {AMOVWZ, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},
368         {ACMP, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0},
369         {ACMP, C_REG, C_REG, C_NONE, C_REG, 70, 4, 0},
370         {ACMP, C_REG, C_NONE, C_NONE, C_ADDCON, 71, 4, 0},
371         {ACMP, C_REG, C_REG, C_NONE, C_ADDCON, 71, 4, 0},
372         {ACMPU, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0},
373         {ACMPU, C_REG, C_REG, C_NONE, C_REG, 70, 4, 0},
374         {ACMPU, C_REG, C_NONE, C_NONE, C_ANDCON, 71, 4, 0},
375         {ACMPU, C_REG, C_REG, C_NONE, C_ANDCON, 71, 4, 0},
376         {AFCMPO, C_FREG, C_NONE, C_NONE, C_FREG, 70, 4, 0},
377         {AFCMPO, C_FREG, C_REG, C_NONE, C_FREG, 70, 4, 0},
378         {ATW, C_LCON, C_REG, C_NONE, C_REG, 60, 4, 0},
379         {ATW, C_LCON, C_REG, C_NONE, C_ADDCON, 61, 4, 0},
380         {ADCBF, C_ZOREG, C_NONE, C_NONE, C_NONE, 43, 4, 0},
381         {ADCBF, C_ZOREG, C_REG, C_NONE, C_NONE, 43, 4, 0},
382         {AECOWX, C_REG, C_REG, C_NONE, C_ZOREG, 44, 4, 0},
383         {AECIWX, C_ZOREG, C_REG, C_NONE, C_REG, 45, 4, 0},
384         {AECOWX, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
385         {AECIWX, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
386         {AEIEIO, C_NONE, C_NONE, C_NONE, C_NONE, 46, 4, 0},
387         {ATLBIE, C_REG, C_NONE, C_NONE, C_NONE, 49, 4, 0},
388         {ATLBIE, C_SCON, C_NONE, C_NONE, C_REG, 49, 4, 0},
389         {ASLBMFEE, C_REG, C_NONE, C_NONE, C_REG, 55, 4, 0},
390         {ASLBMTE, C_REG, C_NONE, C_NONE, C_REG, 55, 4, 0},
391         {ASTSW, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
392         {ASTSW, C_REG, C_NONE, C_LCON, C_ZOREG, 41, 4, 0},
393         {ALSW, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
394         {ALSW, C_ZOREG, C_NONE, C_LCON, C_REG, 42, 4, 0},
395         {obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 78, 4, 0},
396         {obj.AUSEFIELD, C_ADDR, C_NONE, C_NONE, C_NONE, 0, 0, 0},
397         {obj.APCDATA, C_LCON, C_NONE, C_NONE, C_LCON, 0, 0, 0},
398         {obj.AFUNCDATA, C_SCON, C_NONE, C_NONE, C_ADDR, 0, 0, 0},
399         {obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0},
400         {obj.ADUFFZERO, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL
401         {obj.ADUFFCOPY, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL
402
403         {obj.AXXX, C_NONE, C_NONE, C_NONE, C_NONE, 0, 4, 0},
404 }
405
406 var oprange [ALAST & obj.AMask][]Optab
407
408 var xcmp [C_NCLASS][C_NCLASS]bool
409
410 func span9(ctxt *obj.Link, cursym *obj.LSym) {
411         p := cursym.Text
412         if p == nil || p.Link == nil { // handle external functions and ELF section symbols
413                 return
414         }
415         ctxt.Cursym = cursym
416         ctxt.Autosize = int32(p.To.Offset)
417
418         if oprange[AANDN&obj.AMask] == nil {
419                 buildop(ctxt)
420         }
421
422         c := int64(0)
423         p.Pc = c
424
425         var m int
426         var o *Optab
427         for p = p.Link; p != nil; p = p.Link {
428                 ctxt.Curp = p
429                 p.Pc = c
430                 o = oplook(ctxt, p)
431                 m = int(o.size)
432                 if m == 0 {
433                         if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD {
434                                 ctxt.Diag("zero-width instruction\n%v", p)
435                         }
436                         continue
437                 }
438
439                 c += int64(m)
440         }
441
442         cursym.Size = c
443
444         /*
445          * if any procedure is large enough to
446          * generate a large SBRA branch, then
447          * generate extra passes putting branches
448          * around jmps to fix. this is rare.
449          */
450         bflag := 1
451
452         var otxt int64
453         var q *obj.Prog
454         for bflag != 0 {
455                 if ctxt.Debugvlog != 0 {
456                         fmt.Fprintf(ctxt.Bso, "%5.2f span1\n", obj.Cputime())
457                 }
458                 bflag = 0
459                 c = 0
460                 for p = cursym.Text.Link; p != nil; p = p.Link {
461                         p.Pc = c
462                         o = oplook(ctxt, p)
463
464                         // very large conditional branches
465                         if (o.type_ == 16 || o.type_ == 17) && p.Pcond != nil {
466                                 otxt = p.Pcond.Pc - c
467                                 if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 {
468                                         q = ctxt.NewProg()
469                                         q.Link = p.Link
470                                         p.Link = q
471                                         q.As = ABR
472                                         q.To.Type = obj.TYPE_BRANCH
473                                         q.Pcond = p.Pcond
474                                         p.Pcond = q
475                                         q = ctxt.NewProg()
476                                         q.Link = p.Link
477                                         p.Link = q
478                                         q.As = ABR
479                                         q.To.Type = obj.TYPE_BRANCH
480                                         q.Pcond = q.Link.Link
481
482                                         //addnop(p->link);
483                                         //addnop(p);
484                                         bflag = 1
485                                 }
486                         }
487
488                         m = int(o.size)
489                         if m == 0 {
490                                 if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD {
491                                         ctxt.Diag("zero-width instruction\n%v", p)
492                                 }
493                                 continue
494                         }
495
496                         c += int64(m)
497                 }
498
499                 cursym.Size = c
500         }
501
502         c += -c & (FuncAlign - 1)
503         cursym.Size = c
504
505         /*
506          * lay out the code, emitting code and data relocations.
507          */
508
509         cursym.Grow(cursym.Size)
510
511         bp := cursym.P
512         var i int32
513         var out [6]uint32
514         for p := cursym.Text.Link; p != nil; p = p.Link {
515                 ctxt.Pc = p.Pc
516                 ctxt.Curp = p
517                 o = oplook(ctxt, p)
518                 if int(o.size) > 4*len(out) {
519                         log.Fatalf("out array in span9 is too small, need at least %d for %v", o.size/4, p)
520                 }
521                 asmout(ctxt, p, o, out[:])
522                 for i = 0; i < int32(o.size/4); i++ {
523                         ctxt.Arch.ByteOrder.PutUint32(bp, out[i])
524                         bp = bp[4:]
525                 }
526         }
527 }
528
529 func isint32(v int64) bool {
530         return int64(int32(v)) == v
531 }
532
533 func isuint32(v uint64) bool {
534         return uint64(uint32(v)) == v
535 }
536
537 func aclass(ctxt *obj.Link, a *obj.Addr) int {
538         switch a.Type {
539         case obj.TYPE_NONE:
540                 return C_NONE
541
542         case obj.TYPE_REG:
543                 if REG_R0 <= a.Reg && a.Reg <= REG_R31 {
544                         return C_REG
545                 }
546                 if REG_F0 <= a.Reg && a.Reg <= REG_F31 {
547                         return C_FREG
548                 }
549                 if REG_CR0 <= a.Reg && a.Reg <= REG_CR7 || a.Reg == REG_CR {
550                         return C_CREG
551                 }
552                 if REG_SPR0 <= a.Reg && a.Reg <= REG_SPR0+1023 {
553                         switch a.Reg {
554                         case REG_LR:
555                                 return C_LR
556
557                         case REG_XER:
558                                 return C_XER
559
560                         case REG_CTR:
561                                 return C_CTR
562                         }
563
564                         return C_SPR
565                 }
566
567                 if REG_DCR0 <= a.Reg && a.Reg <= REG_DCR0+1023 {
568                         return C_SPR
569                 }
570                 if a.Reg == REG_FPSCR {
571                         return C_FPSCR
572                 }
573                 if a.Reg == REG_MSR {
574                         return C_MSR
575                 }
576                 return C_GOK
577
578         case obj.TYPE_MEM:
579                 switch a.Name {
580                 case obj.NAME_EXTERN,
581                         obj.NAME_STATIC:
582                         if a.Sym == nil {
583                                 break
584                         }
585                         ctxt.Instoffset = a.Offset
586                         if a.Sym != nil { // use relocation
587                                 if a.Sym.Type == obj.STLSBSS {
588                                         if ctxt.Flag_shared {
589                                                 return C_TLS_IE
590                                         } else {
591                                                 return C_TLS_LE
592                                         }
593                                 }
594                                 return C_ADDR
595                         }
596                         return C_LEXT
597
598                 case obj.NAME_GOTREF:
599                         return C_GOTADDR
600
601                 case obj.NAME_AUTO:
602                         ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset
603                         if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
604                                 return C_SAUTO
605                         }
606                         return C_LAUTO
607
608                 case obj.NAME_PARAM:
609                         ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + ctxt.FixedFrameSize()
610                         if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
611                                 return C_SAUTO
612                         }
613                         return C_LAUTO
614
615                 case obj.NAME_NONE:
616                         ctxt.Instoffset = a.Offset
617                         if ctxt.Instoffset == 0 {
618                                 return C_ZOREG
619                         }
620                         if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
621                                 return C_SOREG
622                         }
623                         return C_LOREG
624                 }
625
626                 return C_GOK
627
628         case obj.TYPE_TEXTSIZE:
629                 return C_TEXTSIZE
630
631         case obj.TYPE_CONST,
632                 obj.TYPE_ADDR:
633                 switch a.Name {
634                 case obj.NAME_NONE:
635                         ctxt.Instoffset = a.Offset
636                         if a.Reg != 0 {
637                                 if -BIG <= ctxt.Instoffset && ctxt.Instoffset <= BIG {
638                                         return C_SACON
639                                 }
640                                 if isint32(ctxt.Instoffset) {
641                                         return C_LACON
642                                 }
643                                 return C_DACON
644                         }
645
646                         goto consize
647
648                 case obj.NAME_EXTERN,
649                         obj.NAME_STATIC:
650                         s := a.Sym
651                         if s == nil {
652                                 break
653                         }
654                         if s.Type == obj.SCONST {
655                                 ctxt.Instoffset = a.Offset
656                                 goto consize
657                         }
658
659                         ctxt.Instoffset = a.Offset
660
661                         /* not sure why this barfs */
662                         return C_LCON
663
664                 case obj.NAME_AUTO:
665                         ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset
666                         if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
667                                 return C_SACON
668                         }
669                         return C_LACON
670
671                 case obj.NAME_PARAM:
672                         ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + ctxt.FixedFrameSize()
673                         if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
674                                 return C_SACON
675                         }
676                         return C_LACON
677                 }
678
679                 return C_GOK
680
681         consize:
682                 if ctxt.Instoffset >= 0 {
683                         if ctxt.Instoffset == 0 {
684                                 return C_ZCON
685                         }
686                         if ctxt.Instoffset <= 0x7fff {
687                                 return C_SCON
688                         }
689                         if ctxt.Instoffset <= 0xffff {
690                                 return C_ANDCON
691                         }
692                         if ctxt.Instoffset&0xffff == 0 && isuint32(uint64(ctxt.Instoffset)) { /* && (instoffset & (1<<31)) == 0) */
693                                 return C_UCON
694                         }
695                         if isint32(ctxt.Instoffset) || isuint32(uint64(ctxt.Instoffset)) {
696                                 return C_LCON
697                         }
698                         return C_DCON
699                 }
700
701                 if ctxt.Instoffset >= -0x8000 {
702                         return C_ADDCON
703                 }
704                 if ctxt.Instoffset&0xffff == 0 && isint32(ctxt.Instoffset) {
705                         return C_UCON
706                 }
707                 if isint32(ctxt.Instoffset) {
708                         return C_LCON
709                 }
710                 return C_DCON
711
712         case obj.TYPE_BRANCH:
713                 if a.Sym != nil && ctxt.Flag_dynlink {
714                         return C_LBRAPIC
715                 }
716                 return C_SBRA
717         }
718
719         return C_GOK
720 }
721
722 func prasm(p *obj.Prog) {
723         fmt.Printf("%v\n", p)
724 }
725
726 func oplook(ctxt *obj.Link, p *obj.Prog) *Optab {
727         a1 := int(p.Optab)
728         if a1 != 0 {
729                 return &optab[a1-1]
730         }
731         a1 = int(p.From.Class)
732         if a1 == 0 {
733                 a1 = aclass(ctxt, &p.From) + 1
734                 p.From.Class = int8(a1)
735         }
736
737         a1--
738         a3 := C_NONE + 1
739         if p.From3 != nil {
740                 a3 = int(p.From3.Class)
741                 if a3 == 0 {
742                         a3 = aclass(ctxt, p.From3) + 1
743                         p.From3.Class = int8(a3)
744                 }
745         }
746
747         a3--
748         a4 := int(p.To.Class)
749         if a4 == 0 {
750                 a4 = aclass(ctxt, &p.To) + 1
751                 p.To.Class = int8(a4)
752         }
753
754         a4--
755         a2 := C_NONE
756         if p.Reg != 0 {
757                 a2 = C_REG
758         }
759
760         //print("oplook %v %d %d %d %d\n", p, a1, a2, a3, a4);
761         ops := oprange[p.As&obj.AMask]
762         c1 := &xcmp[a1]
763         c3 := &xcmp[a3]
764         c4 := &xcmp[a4]
765         for i := range ops {
766                 op := &ops[i]
767                 if int(op.a2) == a2 && c1[op.a1] && c3[op.a3] && c4[op.a4] {
768                         p.Optab = uint16(cap(optab) - cap(ops) + i + 1)
769                         return op
770                 }
771         }
772
773         ctxt.Diag("illegal combination %v %v %v %v %v", obj.Aconv(p.As), DRconv(a1), DRconv(a2), DRconv(a3), DRconv(a4))
774         prasm(p)
775         if ops == nil {
776                 ops = optab
777         }
778         return &ops[0]
779 }
780
781 func cmp(a int, b int) bool {
782         if a == b {
783                 return true
784         }
785         switch a {
786         case C_LCON:
787                 if b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON {
788                         return true
789                 }
790
791         case C_ADDCON:
792                 if b == C_ZCON || b == C_SCON {
793                         return true
794                 }
795
796         case C_ANDCON:
797                 if b == C_ZCON || b == C_SCON {
798                         return true
799                 }
800
801         case C_SPR:
802                 if b == C_LR || b == C_XER || b == C_CTR {
803                         return true
804                 }
805
806         case C_UCON:
807                 if b == C_ZCON {
808                         return true
809                 }
810
811         case C_SCON:
812                 if b == C_ZCON {
813                         return true
814                 }
815
816         case C_LACON:
817                 if b == C_SACON {
818                         return true
819                 }
820
821         case C_LBRA:
822                 if b == C_SBRA {
823                         return true
824                 }
825
826         case C_LEXT:
827                 if b == C_SEXT {
828                         return true
829                 }
830
831         case C_LAUTO:
832                 if b == C_SAUTO {
833                         return true
834                 }
835
836         case C_REG:
837                 if b == C_ZCON {
838                         return r0iszero != 0 /*TypeKind(100016)*/
839                 }
840
841         case C_LOREG:
842                 if b == C_ZOREG || b == C_SOREG {
843                         return true
844                 }
845
846         case C_SOREG:
847                 if b == C_ZOREG {
848                         return true
849                 }
850
851         case C_ANY:
852                 return true
853         }
854
855         return false
856 }
857
858 type ocmp []Optab
859
860 func (x ocmp) Len() int {
861         return len(x)
862 }
863
864 func (x ocmp) Swap(i, j int) {
865         x[i], x[j] = x[j], x[i]
866 }
867
868 func (x ocmp) Less(i, j int) bool {
869         p1 := &x[i]
870         p2 := &x[j]
871         n := int(p1.as) - int(p2.as)
872         if n != 0 {
873                 return n < 0
874         }
875         n = int(p1.a1) - int(p2.a1)
876         if n != 0 {
877                 return n < 0
878         }
879         n = int(p1.a2) - int(p2.a2)
880         if n != 0 {
881                 return n < 0
882         }
883         n = int(p1.a3) - int(p2.a3)
884         if n != 0 {
885                 return n < 0
886         }
887         n = int(p1.a4) - int(p2.a4)
888         if n != 0 {
889                 return n < 0
890         }
891         return false
892 }
893 func opset(a, b0 obj.As) {
894         oprange[a&obj.AMask] = oprange[b0]
895 }
896
897 func buildop(ctxt *obj.Link) {
898         var n int
899
900         for i := 0; i < C_NCLASS; i++ {
901                 for n = 0; n < C_NCLASS; n++ {
902                         if cmp(n, i) {
903                                 xcmp[i][n] = true
904                         }
905                 }
906         }
907         for n = 0; optab[n].as != obj.AXXX; n++ {
908         }
909         sort.Sort(ocmp(optab[:n]))
910         for i := 0; i < n; i++ {
911                 r := optab[i].as
912                 r0 := r & obj.AMask
913                 start := i
914                 for optab[i].as == r {
915                         i++
916                 }
917                 oprange[r0] = optab[start:i]
918                 i--
919
920                 switch r {
921                 default:
922                         ctxt.Diag("unknown op in build: %v", obj.Aconv(r))
923                         log.Fatalf("bad code")
924
925                 case ADCBF: /* unary indexed: op (b+a); op (b) */
926                         opset(ADCBI, r0)
927
928                         opset(ADCBST, r0)
929                         opset(ADCBT, r0)
930                         opset(ADCBTST, r0)
931                         opset(ADCBZ, r0)
932                         opset(AICBI, r0)
933
934                 case AECOWX: /* indexed store: op s,(b+a); op s,(b) */
935                         opset(ASTWCCC, r0)
936
937                         opset(ASTDCCC, r0)
938
939                 case AREM: /* macro */
940                         opset(AREMCC, r0)
941
942                         opset(AREMV, r0)
943                         opset(AREMVCC, r0)
944
945                 case AREMU:
946                         opset(AREMU, r0)
947                         opset(AREMUCC, r0)
948                         opset(AREMUV, r0)
949                         opset(AREMUVCC, r0)
950
951                 case AREMD:
952                         opset(AREMDCC, r0)
953                         opset(AREMDV, r0)
954                         opset(AREMDVCC, r0)
955
956                 case AREMDU:
957                         opset(AREMDU, r0)
958                         opset(AREMDUCC, r0)
959                         opset(AREMDUV, r0)
960                         opset(AREMDUVCC, r0)
961
962                 case ADIVW: /* op Rb[,Ra],Rd */
963                         opset(AMULHW, r0)
964
965                         opset(AMULHWCC, r0)
966                         opset(AMULHWU, r0)
967                         opset(AMULHWUCC, r0)
968                         opset(AMULLWCC, r0)
969                         opset(AMULLWVCC, r0)
970                         opset(AMULLWV, r0)
971                         opset(ADIVWCC, r0)
972                         opset(ADIVWV, r0)
973                         opset(ADIVWVCC, r0)
974                         opset(ADIVWU, r0)
975                         opset(ADIVWUCC, r0)
976                         opset(ADIVWUV, r0)
977                         opset(ADIVWUVCC, r0)
978                         opset(AADDCC, r0)
979                         opset(AADDCV, r0)
980                         opset(AADDCVCC, r0)
981                         opset(AADDV, r0)
982                         opset(AADDVCC, r0)
983                         opset(AADDE, r0)
984                         opset(AADDECC, r0)
985                         opset(AADDEV, r0)
986                         opset(AADDEVCC, r0)
987                         opset(ACRAND, r0)
988                         opset(ACRANDN, r0)
989                         opset(ACREQV, r0)
990                         opset(ACRNAND, r0)
991                         opset(ACRNOR, r0)
992                         opset(ACROR, r0)
993                         opset(ACRORN, r0)
994                         opset(ACRXOR, r0)
995                         opset(AMULHD, r0)
996                         opset(AMULHDCC, r0)
997                         opset(AMULHDU, r0)
998                         opset(AMULHDUCC, r0)
999                         opset(AMULLD, r0)
1000                         opset(AMULLDCC, r0)
1001                         opset(AMULLDVCC, r0)
1002                         opset(AMULLDV, r0)
1003                         opset(ADIVD, r0)
1004                         opset(ADIVDCC, r0)
1005                         opset(ADIVDVCC, r0)
1006                         opset(ADIVDV, r0)
1007                         opset(ADIVDU, r0)
1008                         opset(ADIVDUCC, r0)
1009                         opset(ADIVDUVCC, r0)
1010                         opset(ADIVDUCC, r0)
1011
1012                 case AMOVBZ: /* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */
1013                         opset(AMOVH, r0)
1014
1015                         opset(AMOVHZ, r0)
1016
1017                 case AMOVBZU: /* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x, ld[x]u, std[u]x */
1018                         opset(AMOVHU, r0)
1019
1020                         opset(AMOVHZU, r0)
1021                         opset(AMOVWU, r0)
1022                         opset(AMOVWZU, r0)
1023                         opset(AMOVDU, r0)
1024                         opset(AMOVMW, r0)
1025
1026                 case AAND: /* logical op Rb,Rs,Ra; no literal */
1027                         opset(AANDN, r0)
1028
1029                         opset(AANDNCC, r0)
1030                         opset(AEQV, r0)
1031                         opset(AEQVCC, r0)
1032                         opset(ANAND, r0)
1033                         opset(ANANDCC, r0)
1034                         opset(ANOR, r0)
1035                         opset(ANORCC, r0)
1036                         opset(AORCC, r0)
1037                         opset(AORN, r0)
1038                         opset(AORNCC, r0)
1039                         opset(AXORCC, r0)
1040
1041                 case AADDME: /* op Ra, Rd */
1042                         opset(AADDMECC, r0)
1043
1044                         opset(AADDMEV, r0)
1045                         opset(AADDMEVCC, r0)
1046                         opset(AADDZE, r0)
1047                         opset(AADDZECC, r0)
1048                         opset(AADDZEV, r0)
1049                         opset(AADDZEVCC, r0)
1050                         opset(ASUBME, r0)
1051                         opset(ASUBMECC, r0)
1052                         opset(ASUBMEV, r0)
1053                         opset(ASUBMEVCC, r0)
1054                         opset(ASUBZE, r0)
1055                         opset(ASUBZECC, r0)
1056                         opset(ASUBZEV, r0)
1057                         opset(ASUBZEVCC, r0)
1058
1059                 case AADDC:
1060                         opset(AADDCCC, r0)
1061
1062                 case ABEQ:
1063                         opset(ABGE, r0)
1064                         opset(ABGT, r0)
1065                         opset(ABLE, r0)
1066                         opset(ABLT, r0)
1067                         opset(ABNE, r0)
1068                         opset(ABVC, r0)
1069                         opset(ABVS, r0)
1070
1071                 case ABR:
1072                         opset(ABL, r0)
1073
1074                 case ABC:
1075                         opset(ABCL, r0)
1076
1077                 case AEXTSB: /* op Rs, Ra */
1078                         opset(AEXTSBCC, r0)
1079
1080                         opset(AEXTSH, r0)
1081                         opset(AEXTSHCC, r0)
1082                         opset(ACNTLZW, r0)
1083                         opset(ACNTLZWCC, r0)
1084                         opset(ACNTLZD, r0)
1085                         opset(AEXTSW, r0)
1086                         opset(AEXTSWCC, r0)
1087                         opset(ACNTLZDCC, r0)
1088
1089                 case AFABS: /* fop [s,]d */
1090                         opset(AFABSCC, r0)
1091
1092                         opset(AFNABS, r0)
1093                         opset(AFNABSCC, r0)
1094                         opset(AFNEG, r0)
1095                         opset(AFNEGCC, r0)
1096                         opset(AFRSP, r0)
1097                         opset(AFRSPCC, r0)
1098                         opset(AFCTIW, r0)
1099                         opset(AFCTIWCC, r0)
1100                         opset(AFCTIWZ, r0)
1101                         opset(AFCTIWZCC, r0)
1102                         opset(AFCTID, r0)
1103                         opset(AFCTIDCC, r0)
1104                         opset(AFCTIDZ, r0)
1105                         opset(AFCTIDZCC, r0)
1106                         opset(AFCFID, r0)
1107                         opset(AFCFIDCC, r0)
1108                         opset(AFRES, r0)
1109                         opset(AFRESCC, r0)
1110                         opset(AFRSQRTE, r0)
1111                         opset(AFRSQRTECC, r0)
1112                         opset(AFSQRT, r0)
1113                         opset(AFSQRTCC, r0)
1114                         opset(AFSQRTS, r0)
1115                         opset(AFSQRTSCC, r0)
1116
1117                 case AFADD:
1118                         opset(AFADDS, r0)
1119                         opset(AFADDCC, r0)
1120                         opset(AFADDSCC, r0)
1121                         opset(AFDIV, r0)
1122                         opset(AFDIVS, r0)
1123                         opset(AFDIVCC, r0)
1124                         opset(AFDIVSCC, r0)
1125                         opset(AFSUB, r0)
1126                         opset(AFSUBS, r0)
1127                         opset(AFSUBCC, r0)
1128                         opset(AFSUBSCC, r0)
1129
1130                 case AFMADD:
1131                         opset(AFMADDCC, r0)
1132                         opset(AFMADDS, r0)
1133                         opset(AFMADDSCC, r0)
1134                         opset(AFMSUB, r0)
1135                         opset(AFMSUBCC, r0)
1136                         opset(AFMSUBS, r0)
1137                         opset(AFMSUBSCC, r0)
1138                         opset(AFNMADD, r0)
1139                         opset(AFNMADDCC, r0)
1140                         opset(AFNMADDS, r0)
1141                         opset(AFNMADDSCC, r0)
1142                         opset(AFNMSUB, r0)
1143                         opset(AFNMSUBCC, r0)
1144                         opset(AFNMSUBS, r0)
1145                         opset(AFNMSUBSCC, r0)
1146                         opset(AFSEL, r0)
1147                         opset(AFSELCC, r0)
1148
1149                 case AFMUL:
1150                         opset(AFMULS, r0)
1151                         opset(AFMULCC, r0)
1152                         opset(AFMULSCC, r0)
1153
1154                 case AFCMPO:
1155                         opset(AFCMPU, r0)
1156
1157                 case AMTFSB0:
1158                         opset(AMTFSB0CC, r0)
1159                         opset(AMTFSB1, r0)
1160                         opset(AMTFSB1CC, r0)
1161
1162                 case ANEG: /* op [Ra,] Rd */
1163                         opset(ANEGCC, r0)
1164
1165                         opset(ANEGV, r0)
1166                         opset(ANEGVCC, r0)
1167
1168                 case AOR: /* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,Ra; oris/xoris $uimm,Rs,Ra */
1169                         opset(AXOR, r0)
1170
1171                 case ASLW:
1172                         opset(ASLWCC, r0)
1173                         opset(ASRW, r0)
1174                         opset(ASRWCC, r0)
1175
1176                 case ASLD:
1177                         opset(ASLDCC, r0)
1178                         opset(ASRD, r0)
1179                         opset(ASRDCC, r0)
1180
1181                 case ASRAW: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
1182                         opset(ASRAWCC, r0)
1183
1184                 case ASRAD: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
1185                         opset(ASRADCC, r0)
1186
1187                 case ASUB: /* SUB Ra,Rb,Rd => subf Rd,ra,rb */
1188                         opset(ASUB, r0)
1189
1190                         opset(ASUBCC, r0)
1191                         opset(ASUBV, r0)
1192                         opset(ASUBVCC, r0)
1193                         opset(ASUBCCC, r0)
1194                         opset(ASUBCV, r0)
1195                         opset(ASUBCVCC, r0)
1196                         opset(ASUBE, r0)
1197                         opset(ASUBECC, r0)
1198                         opset(ASUBEV, r0)
1199                         opset(ASUBEVCC, r0)
1200
1201                 case ASYNC:
1202                         opset(AISYNC, r0)
1203                         opset(APTESYNC, r0)
1204                         opset(ATLBSYNC, r0)
1205
1206                 case ARLWMI:
1207                         opset(ARLWMICC, r0)
1208                         opset(ARLWNM, r0)
1209                         opset(ARLWNMCC, r0)
1210
1211                 case ARLDMI:
1212                         opset(ARLDMICC, r0)
1213
1214                 case ARLDC:
1215                         opset(ARLDCCC, r0)
1216
1217                 case ARLDCL:
1218                         opset(ARLDCR, r0)
1219                         opset(ARLDCLCC, r0)
1220                         opset(ARLDCRCC, r0)
1221
1222                 case AFMOVD:
1223                         opset(AFMOVDCC, r0)
1224                         opset(AFMOVDU, r0)
1225                         opset(AFMOVS, r0)
1226                         opset(AFMOVSU, r0)
1227
1228                 case AECIWX:
1229                         opset(ALWAR, r0)
1230                         opset(ALDAR, r0)
1231
1232                 case ASYSCALL: /* just the op; flow of control */
1233                         opset(ARFI, r0)
1234
1235                         opset(ARFCI, r0)
1236                         opset(ARFID, r0)
1237                         opset(AHRFID, r0)
1238
1239                 case AMOVHBR:
1240                         opset(AMOVWBR, r0)
1241
1242                 case ASLBMFEE:
1243                         opset(ASLBMFEV, r0)
1244
1245                 case ATW:
1246                         opset(ATD, r0)
1247
1248                 case ATLBIE:
1249                         opset(ASLBIE, r0)
1250                         opset(ATLBIEL, r0)
1251
1252                 case AEIEIO:
1253                         opset(ASLBIA, r0)
1254
1255                 case ACMP:
1256                         opset(ACMPW, r0)
1257
1258                 case ACMPU:
1259                         opset(ACMPWU, r0)
1260
1261                 case AADD,
1262                         AANDCC, /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra; andis. $uimm,Rs,Ra */
1263                         ALSW,
1264                         AMOVW,
1265                         /* load/store/move word with sign extension; special 32-bit move; move 32-bit literals */
1266                         AMOVWZ, /* load/store/move word with zero extension; move 32-bit literals  */
1267                         AMOVD,  /* load/store/move 64-bit values, including 32-bit literals with/without sign-extension */
1268                         AMOVB,  /* macro: move byte with sign extension */
1269                         AMOVBU, /* macro: move byte with sign extension & update */
1270                         AMOVFL,
1271                         AMULLW,
1272                         /* op $s[,r2],r3; op r1[,r2],r3; no cc/v */
1273                         ASUBC, /* op r1,$s,r3; op r1[,r2],r3 */
1274                         ASTSW,
1275                         ASLBMTE,
1276                         AWORD,
1277                         ADWORD,
1278                         obj.ANOP,
1279                         obj.ATEXT,
1280                         obj.AUNDEF,
1281                         obj.AUSEFIELD,
1282                         obj.AFUNCDATA,
1283                         obj.APCDATA,
1284                         obj.ADUFFZERO,
1285                         obj.ADUFFCOPY:
1286                         break
1287                 }
1288         }
1289 }
1290
1291 func OPVCC(o uint32, xo uint32, oe uint32, rc uint32) uint32 {
1292         return o<<26 | xo<<1 | oe<<10 | rc&1
1293 }
1294
1295 func OPCC(o uint32, xo uint32, rc uint32) uint32 {
1296         return OPVCC(o, xo, 0, rc)
1297 }
1298
1299 func OP(o uint32, xo uint32) uint32 {
1300         return OPVCC(o, xo, 0, 0)
1301 }
1302
1303 /* the order is dest, a/s, b/imm for both arithmetic and logical operations */
1304 func AOP_RRR(op uint32, d uint32, a uint32, b uint32) uint32 {
1305         return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11
1306 }
1307
1308 func AOP_IRR(op uint32, d uint32, a uint32, simm uint32) uint32 {
1309         return op | (d&31)<<21 | (a&31)<<16 | simm&0xFFFF
1310 }
1311
1312 func LOP_RRR(op uint32, a uint32, s uint32, b uint32) uint32 {
1313         return op | (s&31)<<21 | (a&31)<<16 | (b&31)<<11
1314 }
1315
1316 func LOP_IRR(op uint32, a uint32, s uint32, uimm uint32) uint32 {
1317         return op | (s&31)<<21 | (a&31)<<16 | uimm&0xFFFF
1318 }
1319
1320 func OP_BR(op uint32, li uint32, aa uint32) uint32 {
1321         return op | li&0x03FFFFFC | aa<<1
1322 }
1323
1324 func OP_BC(op uint32, bo uint32, bi uint32, bd uint32, aa uint32) uint32 {
1325         return op | (bo&0x1F)<<21 | (bi&0x1F)<<16 | bd&0xFFFC | aa<<1
1326 }
1327
1328 func OP_BCR(op uint32, bo uint32, bi uint32) uint32 {
1329         return op | (bo&0x1F)<<21 | (bi&0x1F)<<16
1330 }
1331
1332 func OP_RLW(op uint32, a uint32, s uint32, sh uint32, mb uint32, me uint32) uint32 {
1333         return op | (s&31)<<21 | (a&31)<<16 | (sh&31)<<11 | (mb&31)<<6 | (me&31)<<1
1334 }
1335
1336 const (
1337         /* each rhs is OPVCC(_, _, _, _) */
1338         OP_ADD    = 31<<26 | 266<<1 | 0<<10 | 0
1339         OP_ADDI   = 14<<26 | 0<<1 | 0<<10 | 0
1340         OP_ADDIS  = 15<<26 | 0<<1 | 0<<10 | 0
1341         OP_ANDI   = 28<<26 | 0<<1 | 0<<10 | 0
1342         OP_EXTSB  = 31<<26 | 954<<1 | 0<<10 | 0
1343         OP_EXTSH  = 31<<26 | 922<<1 | 0<<10 | 0
1344         OP_EXTSW  = 31<<26 | 986<<1 | 0<<10 | 0
1345         OP_MCRF   = 19<<26 | 0<<1 | 0<<10 | 0
1346         OP_MCRFS  = 63<<26 | 64<<1 | 0<<10 | 0
1347         OP_MCRXR  = 31<<26 | 512<<1 | 0<<10 | 0
1348         OP_MFCR   = 31<<26 | 19<<1 | 0<<10 | 0
1349         OP_MFFS   = 63<<26 | 583<<1 | 0<<10 | 0
1350         OP_MFMSR  = 31<<26 | 83<<1 | 0<<10 | 0
1351         OP_MFSPR  = 31<<26 | 339<<1 | 0<<10 | 0
1352         OP_MFSR   = 31<<26 | 595<<1 | 0<<10 | 0
1353         OP_MFSRIN = 31<<26 | 659<<1 | 0<<10 | 0
1354         OP_MTCRF  = 31<<26 | 144<<1 | 0<<10 | 0
1355         OP_MTFSF  = 63<<26 | 711<<1 | 0<<10 | 0
1356         OP_MTFSFI = 63<<26 | 134<<1 | 0<<10 | 0
1357         OP_MTMSR  = 31<<26 | 146<<1 | 0<<10 | 0
1358         OP_MTMSRD = 31<<26 | 178<<1 | 0<<10 | 0
1359         OP_MTSPR  = 31<<26 | 467<<1 | 0<<10 | 0
1360         OP_MTSR   = 31<<26 | 210<<1 | 0<<10 | 0
1361         OP_MTSRIN = 31<<26 | 242<<1 | 0<<10 | 0
1362         OP_MULLW  = 31<<26 | 235<<1 | 0<<10 | 0
1363         OP_MULLD  = 31<<26 | 233<<1 | 0<<10 | 0
1364         OP_OR     = 31<<26 | 444<<1 | 0<<10 | 0
1365         OP_ORI    = 24<<26 | 0<<1 | 0<<10 | 0
1366         OP_ORIS   = 25<<26 | 0<<1 | 0<<10 | 0
1367         OP_RLWINM = 21<<26 | 0<<1 | 0<<10 | 0
1368         OP_SUBF   = 31<<26 | 40<<1 | 0<<10 | 0
1369         OP_RLDIC  = 30<<26 | 4<<1 | 0<<10 | 0
1370         OP_RLDICR = 30<<26 | 2<<1 | 0<<10 | 0
1371         OP_RLDICL = 30<<26 | 0<<1 | 0<<10 | 0
1372 )
1373
1374 func oclass(a *obj.Addr) int {
1375         return int(a.Class) - 1
1376 }
1377
1378 const (
1379         D_FORM = iota
1380         DS_FORM
1381 )
1382
1383 // opform returns the form (D_FORM or DS_FORM) of an instruction. Used to decide on
1384 // which relocation to use with a load or store and only supports the needed
1385 // instructions.
1386 func opform(ctxt *obj.Link, insn uint32) int {
1387         switch insn {
1388         default:
1389                 ctxt.Diag("bad insn in loadform: %x", insn)
1390         case OPVCC(58, 0, 0, 0), // ld
1391                 OPVCC(58, 0, 0, 0) | 1<<1, // lwa
1392                 OPVCC(62, 0, 0, 0):        // std
1393                 return DS_FORM
1394         case OP_ADDI, // add
1395                 OPVCC(32, 0, 0, 0), // lwz
1396                 OPVCC(42, 0, 0, 0), // lha
1397                 OPVCC(40, 0, 0, 0), // lhz
1398                 OPVCC(34, 0, 0, 0), // lbz
1399                 OPVCC(50, 0, 0, 0), // lfd
1400                 OPVCC(48, 0, 0, 0), // lfs
1401                 OPVCC(36, 0, 0, 0), // stw
1402                 OPVCC(44, 0, 0, 0), // sth
1403                 OPVCC(38, 0, 0, 0), // stb
1404                 OPVCC(54, 0, 0, 0), // stfd
1405                 OPVCC(52, 0, 0, 0): // stfs
1406                 return D_FORM
1407         }
1408         return 0
1409 }
1410
1411 // Encode instructions and create relocation for accessing s+d according to the
1412 // instruction op with source or destination (as appropriate) register reg.
1413 func symbolAccess(ctxt *obj.Link, s *obj.LSym, d int64, reg int16, op uint32) (o1, o2 uint32) {
1414         var base uint32
1415         form := opform(ctxt, op)
1416         if ctxt.Flag_shared {
1417                 base = REG_R2
1418         } else {
1419                 base = REG_R0
1420         }
1421         o1 = AOP_IRR(OP_ADDIS, REGTMP, base, 0)
1422         o2 = AOP_IRR(op, uint32(reg), REGTMP, 0)
1423         rel := obj.Addrel(ctxt.Cursym)
1424         rel.Off = int32(ctxt.Pc)
1425         rel.Siz = 8
1426         rel.Sym = s
1427         rel.Add = d
1428         if ctxt.Flag_shared {
1429                 switch form {
1430                 case D_FORM:
1431                         rel.Type = obj.R_ADDRPOWER_TOCREL
1432                 case DS_FORM:
1433                         rel.Type = obj.R_ADDRPOWER_TOCREL_DS
1434                 }
1435
1436         } else {
1437                 switch form {
1438                 case D_FORM:
1439                         rel.Type = obj.R_ADDRPOWER
1440                 case DS_FORM:
1441                         rel.Type = obj.R_ADDRPOWER_DS
1442                 }
1443         }
1444         return
1445 }
1446
1447 /*
1448  * 32-bit masks
1449  */
1450 func getmask(m []byte, v uint32) bool {
1451         m[1] = 0
1452         m[0] = m[1]
1453         if v != ^uint32(0) && v&(1<<31) != 0 && v&1 != 0 { /* MB > ME */
1454                 if getmask(m, ^v) {
1455                         i := int(m[0])
1456                         m[0] = m[1] + 1
1457                         m[1] = byte(i - 1)
1458                         return true
1459                 }
1460
1461                 return false
1462         }
1463
1464         for i := 0; i < 32; i++ {
1465                 if v&(1<<uint(31-i)) != 0 {
1466                         m[0] = byte(i)
1467                         for {
1468                                 m[1] = byte(i)
1469                                 i++
1470                                 if i >= 32 || v&(1<<uint(31-i)) == 0 {
1471                                         break
1472                                 }
1473                         }
1474
1475                         for ; i < 32; i++ {
1476                                 if v&(1<<uint(31-i)) != 0 {
1477                                         return false
1478                                 }
1479                         }
1480                         return true
1481                 }
1482         }
1483
1484         return false
1485 }
1486
1487 func maskgen(ctxt *obj.Link, p *obj.Prog, m []byte, v uint32) {
1488         if !getmask(m, v) {
1489                 ctxt.Diag("cannot generate mask #%x\n%v", v, p)
1490         }
1491 }
1492
1493 /*
1494  * 64-bit masks (rldic etc)
1495  */
1496 func getmask64(m []byte, v uint64) bool {
1497         m[1] = 0
1498         m[0] = m[1]
1499         for i := 0; i < 64; i++ {
1500                 if v&(uint64(1)<<uint(63-i)) != 0 {
1501                         m[0] = byte(i)
1502                         for {
1503                                 m[1] = byte(i)
1504                                 i++
1505                                 if i >= 64 || v&(uint64(1)<<uint(63-i)) == 0 {
1506                                         break
1507                                 }
1508                         }
1509
1510                         for ; i < 64; i++ {
1511                                 if v&(uint64(1)<<uint(63-i)) != 0 {
1512                                         return false
1513                                 }
1514                         }
1515                         return true
1516                 }
1517         }
1518
1519         return false
1520 }
1521
1522 func maskgen64(ctxt *obj.Link, p *obj.Prog, m []byte, v uint64) {
1523         if !getmask64(m, v) {
1524                 ctxt.Diag("cannot generate mask #%x\n%v", v, p)
1525         }
1526 }
1527
1528 func loadu32(r int, d int64) uint32 {
1529         v := int32(d >> 16)
1530         if isuint32(uint64(d)) {
1531                 return LOP_IRR(OP_ORIS, uint32(r), REGZERO, uint32(v))
1532         }
1533         return AOP_IRR(OP_ADDIS, uint32(r), REGZERO, uint32(v))
1534 }
1535
1536 func high16adjusted(d int32) uint16 {
1537         if d&0x8000 != 0 {
1538                 return uint16((d >> 16) + 1)
1539         }
1540         return uint16(d >> 16)
1541 }
1542
1543 func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
1544         o1 := uint32(0)
1545         o2 := uint32(0)
1546         o3 := uint32(0)
1547         o4 := uint32(0)
1548         o5 := uint32(0)
1549
1550         //print("%v => case %d\n", p, o->type);
1551         switch o.type_ {
1552         default:
1553                 ctxt.Diag("unknown type %d", o.type_)
1554                 prasm(p)
1555
1556         case 0: /* pseudo ops */
1557                 break
1558
1559         case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */
1560                 if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
1561                         v := regoff(ctxt, &p.From)
1562                         if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
1563                                 //nerrors--;
1564                                 ctxt.Diag("literal operation on R0\n%v", p)
1565                         }
1566
1567                         o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v))
1568                         break
1569                 }
1570
1571                 o1 = LOP_RRR(OP_OR, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.From.Reg))
1572
1573         case 2: /* int/cr/fp op Rb,[Ra],Rd */
1574                 r := int(p.Reg)
1575
1576                 if r == 0 {
1577                         r = int(p.To.Reg)
1578                 }
1579                 o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
1580
1581         case 3: /* mov $soreg/addcon/ucon, r ==> addis/addi $i,reg',r */
1582                 d := vregoff(ctxt, &p.From)
1583
1584                 v := int32(d)
1585                 r := int(p.From.Reg)
1586                 if r == 0 {
1587                         r = int(o.param)
1588                 }
1589                 if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 && (r != 0 || v != 0) {
1590                         ctxt.Diag("literal operation on R0\n%v", p)
1591                 }
1592                 a := OP_ADDI
1593                 if o.a1 == C_UCON {
1594                         if d&0xffff != 0 {
1595                                 log.Fatalf("invalid handling of %v", p)
1596                         }
1597                         v >>= 16
1598                         if r == REGZERO && isuint32(uint64(d)) {
1599                                 o1 = LOP_IRR(OP_ORIS, uint32(p.To.Reg), REGZERO, uint32(v))
1600                                 break
1601                         }
1602
1603                         a = OP_ADDIS
1604                 } else {
1605                         if int64(int16(d)) != d {
1606                                 log.Fatalf("invalid handling of %v", p)
1607                         }
1608                 }
1609
1610                 o1 = AOP_IRR(uint32(a), uint32(p.To.Reg), uint32(r), uint32(v))
1611
1612         case 4: /* add/mul $scon,[r1],r2 */
1613                 v := regoff(ctxt, &p.From)
1614
1615                 r := int(p.Reg)
1616                 if r == 0 {
1617                         r = int(p.To.Reg)
1618                 }
1619                 if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 {
1620                         ctxt.Diag("literal operation on R0\n%v", p)
1621                 }
1622                 if int32(int16(v)) != v {
1623                         log.Fatalf("mishandled instruction %v", p)
1624                 }
1625                 o1 = AOP_IRR(opirr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(v))
1626
1627         case 5: /* syscall */
1628                 o1 = oprrr(ctxt, p.As)
1629
1630         case 6: /* logical op Rb,[Rs,]Ra; no literal */
1631                 r := int(p.Reg)
1632
1633                 if r == 0 {
1634                         r = int(p.To.Reg)
1635                 }
1636                 o1 = LOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
1637
1638         case 7: /* mov r, soreg ==> stw o(r) */
1639                 r := int(p.To.Reg)
1640
1641                 if r == 0 {
1642                         r = int(o.param)
1643                 }
1644                 v := regoff(ctxt, &p.To)
1645                 if p.To.Type == obj.TYPE_MEM && p.To.Index != 0 {
1646                         if v != 0 {
1647                                 ctxt.Diag("illegal indexed instruction\n%v", p)
1648                         }
1649                         if ctxt.Flag_shared && r == REG_R13 {
1650                                 rel := obj.Addrel(ctxt.Cursym)
1651                                 rel.Off = int32(ctxt.Pc)
1652                                 rel.Siz = 4
1653                                 // This (and the matching part in the load case
1654                                 // below) are the only places in the ppc64 toolchain
1655                                 // that knows the name of the tls variable. Possibly
1656                                 // we could add some assembly syntax so that the name
1657                                 // of the variable does not have to be assumed.
1658                                 rel.Sym = obj.Linklookup(ctxt, "runtime.tls_g", 0)
1659                                 rel.Type = obj.R_POWER_TLS
1660                         }
1661                         o1 = AOP_RRR(opstorex(ctxt, p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(r))
1662                 } else {
1663                         if int32(int16(v)) != v {
1664                                 log.Fatalf("mishandled instruction %v", p)
1665                         }
1666                         o1 = AOP_IRR(opstore(ctxt, p.As), uint32(p.From.Reg), uint32(r), uint32(v))
1667                 }
1668
1669         case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r) */
1670                 r := int(p.From.Reg)
1671
1672                 if r == 0 {
1673                         r = int(o.param)
1674                 }
1675                 v := regoff(ctxt, &p.From)
1676                 if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 {
1677                         if v != 0 {
1678                                 ctxt.Diag("illegal indexed instruction\n%v", p)
1679                         }
1680                         if ctxt.Flag_shared && r == REG_R13 {
1681                                 rel := obj.Addrel(ctxt.Cursym)
1682                                 rel.Off = int32(ctxt.Pc)
1683                                 rel.Siz = 4
1684                                 rel.Sym = obj.Linklookup(ctxt, "runtime.tls_g", 0)
1685                                 rel.Type = obj.R_POWER_TLS
1686                         }
1687                         o1 = AOP_RRR(oploadx(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))
1688                 } else {
1689                         if int32(int16(v)) != v {
1690                                 log.Fatalf("mishandled instruction %v", p)
1691                         }
1692                         o1 = AOP_IRR(opload(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(v))
1693                 }
1694
1695         case 9: /* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */
1696                 r := int(p.From.Reg)
1697
1698                 if r == 0 {
1699                         r = int(o.param)
1700                 }
1701                 v := regoff(ctxt, &p.From)
1702                 if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 {
1703                         if v != 0 {
1704                                 ctxt.Diag("illegal indexed instruction\n%v", p)
1705                         }
1706                         o1 = AOP_RRR(oploadx(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))
1707                 } else {
1708                         o1 = AOP_IRR(opload(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(v))
1709                 }
1710                 o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
1711
1712         case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */
1713                 r := int(p.Reg)
1714
1715                 if r == 0 {
1716                         r = int(p.To.Reg)
1717                 }
1718                 o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(r))
1719
1720         case 11: /* br/bl lbra */
1721                 v := int32(0)
1722
1723                 if p.Pcond != nil {
1724                         v = int32(p.Pcond.Pc - p.Pc)
1725                         if v&03 != 0 {
1726                                 ctxt.Diag("odd branch target address\n%v", p)
1727                                 v &^= 03
1728                         }
1729
1730                         if v < -(1<<25) || v >= 1<<24 {
1731                                 ctxt.Diag("branch too far\n%v", p)
1732                         }
1733                 }
1734
1735                 o1 = OP_BR(opirr(ctxt, p.As), uint32(v), 0)
1736                 if p.To.Sym != nil {
1737                         rel := obj.Addrel(ctxt.Cursym)
1738                         rel.Off = int32(ctxt.Pc)
1739                         rel.Siz = 4
1740                         rel.Sym = p.To.Sym
1741                         v += int32(p.To.Offset)
1742                         if v&03 != 0 {
1743                                 ctxt.Diag("odd branch target address\n%v", p)
1744                                 v &^= 03
1745                         }
1746
1747                         rel.Add = int64(v)
1748                         rel.Type = obj.R_CALLPOWER
1749                 }
1750                 o2 = 0x60000000 // nop, sometimes overwritten by ld r2, 24(r1) when dynamic linking
1751
1752         case 12: /* movb r,r (extsb); movw r,r (extsw) */
1753                 if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
1754                         v := regoff(ctxt, &p.From)
1755                         if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
1756                                 ctxt.Diag("literal operation on R0\n%v", p)
1757                         }
1758
1759                         o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v))
1760                         break
1761                 }
1762
1763                 if p.As == AMOVW {
1764                         o1 = LOP_RRR(OP_EXTSW, uint32(p.To.Reg), uint32(p.From.Reg), 0)
1765                 } else {
1766                         o1 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.From.Reg), 0)
1767                 }
1768
1769         case 13: /* mov[bhw]z r,r; uses rlwinm not andi. to avoid changing CC */
1770                 if p.As == AMOVBZ {
1771                         o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 24, 31)
1772                 } else if p.As == AMOVH {
1773                         o1 = LOP_RRR(OP_EXTSH, uint32(p.To.Reg), uint32(p.From.Reg), 0)
1774                 } else if p.As == AMOVHZ {
1775                         o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 16, 31)
1776                 } else if p.As == AMOVWZ {
1777                         o1 = OP_RLW(OP_RLDIC, uint32(p.To.Reg), uint32(p.From.Reg), 0, 0, 0) | 1<<5 /* MB=32 */
1778                 } else {
1779                         ctxt.Diag("internal: bad mov[bhw]z\n%v", p)
1780                 }
1781
1782         case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */
1783                 r := int(p.Reg)
1784
1785                 if r == 0 {
1786                         r = int(p.To.Reg)
1787                 }
1788                 d := vregoff(ctxt, p.From3)
1789                 var mask [2]uint8
1790                 maskgen64(ctxt, p, mask[:], uint64(d))
1791                 var a int
1792                 switch p.As {
1793                 case ARLDCL, ARLDCLCC:
1794                         a = int(mask[0]) /* MB */
1795                         if mask[1] != 63 {
1796                                 ctxt.Diag("invalid mask for rotate: %x (end != bit 63)\n%v", uint64(d), p)
1797                         }
1798
1799                 case ARLDCR, ARLDCRCC:
1800                         a = int(mask[1]) /* ME */
1801                         if mask[0] != 0 {
1802                                 ctxt.Diag("invalid mask for rotate: %x (start != 0)\n%v", uint64(d), p)
1803                         }
1804
1805                 default:
1806                         ctxt.Diag("unexpected op in rldc case\n%v", p)
1807                         a = 0
1808                 }
1809
1810                 o1 = LOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
1811                 o1 |= (uint32(a) & 31) << 6
1812                 if a&0x20 != 0 {
1813                         o1 |= 1 << 5 /* mb[5] is top bit */
1814                 }
1815
1816         case 17, /* bc bo,bi,lbra (same for now) */
1817                 16: /* bc bo,bi,sbra */
1818                 a := 0
1819
1820                 if p.From.Type == obj.TYPE_CONST {
1821                         a = int(regoff(ctxt, &p.From))
1822                 }
1823                 r := int(p.Reg)
1824                 if r == 0 {
1825                         r = 0
1826                 }
1827                 v := int32(0)
1828                 if p.Pcond != nil {
1829                         v = int32(p.Pcond.Pc - p.Pc)
1830                 }
1831                 if v&03 != 0 {
1832                         ctxt.Diag("odd branch target address\n%v", p)
1833                         v &^= 03
1834                 }
1835
1836                 if v < -(1<<16) || v >= 1<<15 {
1837                         ctxt.Diag("branch too far\n%v", p)
1838                 }
1839                 o1 = OP_BC(opirr(ctxt, p.As), uint32(a), uint32(r), uint32(v), 0)
1840
1841         case 15: /* br/bl (r) => mov r,lr; br/bl (lr) */
1842                 var v int32
1843                 if p.As == ABC || p.As == ABCL {
1844                         v = regoff(ctxt, &p.To) & 31
1845                 } else {
1846                         v = 20 /* unconditional */
1847                 }
1848                 o1 = AOP_RRR(OP_MTSPR, uint32(p.To.Reg), 0, 0) | (REG_LR&0x1f)<<16 | ((REG_LR>>5)&0x1f)<<11
1849                 o2 = OPVCC(19, 16, 0, 0)
1850                 if p.As == ABL || p.As == ABCL {
1851                         o2 |= 1
1852                 }
1853                 o2 = OP_BCR(o2, uint32(v), uint32(p.To.Index))
1854
1855         case 18: /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */
1856                 var v int32
1857                 if p.As == ABC || p.As == ABCL {
1858                         v = regoff(ctxt, &p.From) & 31
1859                 } else {
1860                         v = 20 /* unconditional */
1861                 }
1862                 r := int(p.Reg)
1863                 if r == 0 {
1864                         r = 0
1865                 }
1866                 switch oclass(&p.To) {
1867                 case C_CTR:
1868                         o1 = OPVCC(19, 528, 0, 0)
1869
1870                 case C_LR:
1871                         o1 = OPVCC(19, 16, 0, 0)
1872
1873                 default:
1874                         ctxt.Diag("bad optab entry (18): %d\n%v", p.To.Class, p)
1875                         v = 0
1876                 }
1877
1878                 if p.As == ABL || p.As == ABCL {
1879                         o1 |= 1
1880                 }
1881                 o1 = OP_BCR(o1, uint32(v), uint32(r))
1882
1883         case 19: /* mov $lcon,r ==> cau+or */
1884                 d := vregoff(ctxt, &p.From)
1885
1886                 if p.From.Sym == nil {
1887                         o1 = loadu32(int(p.To.Reg), d)
1888                         o2 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(int32(d)))
1889                 } else {
1890                         o1, o2 = symbolAccess(ctxt, p.From.Sym, d, p.To.Reg, OP_ADDI)
1891                 }
1892
1893         //if(dlm) reloc(&p->from, p->pc, 0);
1894
1895         case 20: /* add $ucon,,r */
1896                 v := regoff(ctxt, &p.From)
1897
1898                 r := int(p.Reg)
1899                 if r == 0 {
1900                         r = int(p.To.Reg)
1901                 }
1902                 if p.As == AADD && (r0iszero == 0 /*TypeKind(100016)*/ && p.Reg == 0 || r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0) {
1903                         ctxt.Diag("literal operation on R0\n%v", p)
1904                 }
1905                 o1 = AOP_IRR(opirr(ctxt, -p.As), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
1906
1907         case 22: /* add $lcon,r1,r2 ==> cau+or+add */ /* could do add/sub more efficiently */
1908                 if p.To.Reg == REGTMP || p.Reg == REGTMP {
1909                         ctxt.Diag("can't synthesize large constant\n%v", p)
1910                 }
1911                 d := vregoff(ctxt, &p.From)
1912                 o1 = loadu32(REGTMP, d)
1913                 o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
1914                 r := int(p.Reg)
1915                 if r == 0 {
1916                         r = int(p.To.Reg)
1917                 }
1918                 o3 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), REGTMP, uint32(r))
1919                 if p.From.Sym != nil {
1920                         ctxt.Diag("%v is not supported", p)
1921                 }
1922
1923         //if(dlm) reloc(&p->from, p->pc, 0);
1924
1925         case 23: /* and $lcon,r1,r2 ==> cau+or+and */ /* masks could be done using rlnm etc. */
1926                 if p.To.Reg == REGTMP || p.Reg == REGTMP {
1927                         ctxt.Diag("can't synthesize large constant\n%v", p)
1928                 }
1929                 d := vregoff(ctxt, &p.From)
1930                 o1 = loadu32(REGTMP, d)
1931                 o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
1932                 r := int(p.Reg)
1933                 if r == 0 {
1934                         r = int(p.To.Reg)
1935                 }
1936                 o3 = LOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), REGTMP, uint32(r))
1937                 if p.From.Sym != nil {
1938                         ctxt.Diag("%v is not supported", p)
1939                 }
1940
1941                 //if(dlm) reloc(&p->from, p->pc, 0);
1942
1943                 /*24*/
1944         case 25:
1945                 /* sld[.] $sh,rS,rA -> rldicr[.] $sh,rS,mask(0,63-sh),rA; srd[.] -> rldicl */
1946                 v := regoff(ctxt, &p.From)
1947
1948                 if v < 0 {
1949                         v = 0
1950                 } else if v > 63 {
1951                         v = 63
1952                 }
1953                 r := int(p.Reg)
1954                 if r == 0 {
1955                         r = int(p.To.Reg)
1956                 }
1957                 var a int
1958                 switch p.As {
1959                 case ASLD, ASLDCC:
1960                         a = int(63 - v)
1961                         o1 = OP_RLDICR
1962
1963                 case ASRD, ASRDCC:
1964                         a = int(v)
1965                         v = 64 - v
1966                         o1 = OP_RLDICL
1967
1968                 default:
1969                         ctxt.Diag("unexpected op in sldi case\n%v", p)
1970                         a = 0
1971                         o1 = 0
1972                 }
1973
1974                 o1 = AOP_RRR(o1, uint32(r), uint32(p.To.Reg), (uint32(v) & 0x1F))
1975                 o1 |= (uint32(a) & 31) << 6
1976                 if v&0x20 != 0 {
1977                         o1 |= 1 << 1
1978                 }
1979                 if a&0x20 != 0 {
1980                         o1 |= 1 << 5 /* mb[5] is top bit */
1981                 }
1982                 if p.As == ASLDCC || p.As == ASRDCC {
1983                         o1 |= 1 /* Rc */
1984                 }
1985
1986         case 26: /* mov $lsext/auto/oreg,,r2 ==> addis+addi */
1987                 if p.To.Reg == REGTMP {
1988                         ctxt.Diag("can't synthesize large constant\n%v", p)
1989                 }
1990                 v := regoff(ctxt, &p.From)
1991                 r := int(p.From.Reg)
1992                 if r == 0 {
1993                         r = int(o.param)
1994                 }
1995                 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
1996                 o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(v))
1997
1998         case 27: /* subc ra,$simm,rd => subfic rd,ra,$simm */
1999                 v := regoff(ctxt, p.From3)
2000
2001                 r := int(p.From.Reg)
2002                 o1 = AOP_IRR(opirr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2003
2004         case 28: /* subc r1,$lcon,r2 ==> cau+or+subfc */
2005                 if p.To.Reg == REGTMP || p.From.Reg == REGTMP {
2006                         ctxt.Diag("can't synthesize large constant\n%v", p)
2007                 }
2008                 v := regoff(ctxt, p.From3)
2009                 o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(v)>>16)
2010                 o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(v))
2011                 o3 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Reg), REGTMP)
2012                 if p.From.Sym != nil {
2013                         ctxt.Diag("%v is not supported", p)
2014                 }
2015
2016         //if(dlm) reloc(&p->from3, p->pc, 0);
2017
2018         case 29: /* rldic[lr]? $sh,s,$mask,a -- left, right, plain give different masks */
2019                 v := regoff(ctxt, &p.From)
2020
2021                 d := vregoff(ctxt, p.From3)
2022                 var mask [2]uint8
2023                 maskgen64(ctxt, p, mask[:], uint64(d))
2024                 var a int
2025                 switch p.As {
2026                 case ARLDC, ARLDCCC:
2027                         a = int(mask[0]) /* MB */
2028                         if int32(mask[1]) != (63 - v) {
2029                                 ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p)
2030                         }
2031
2032                 case ARLDCL, ARLDCLCC:
2033                         a = int(mask[0]) /* MB */
2034                         if mask[1] != 63 {
2035                                 ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p)
2036                         }
2037
2038                 case ARLDCR, ARLDCRCC:
2039                         a = int(mask[1]) /* ME */
2040                         if mask[0] != 0 {
2041                                 ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p)
2042                         }
2043
2044                 default:
2045                         ctxt.Diag("unexpected op in rldic case\n%v", p)
2046                         a = 0
2047                 }
2048
2049                 o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
2050                 o1 |= (uint32(a) & 31) << 6
2051                 if v&0x20 != 0 {
2052                         o1 |= 1 << 1
2053                 }
2054                 if a&0x20 != 0 {
2055                         o1 |= 1 << 5 /* mb[5] is top bit */
2056                 }
2057
2058         case 30: /* rldimi $sh,s,$mask,a */
2059                 v := regoff(ctxt, &p.From)
2060
2061                 d := vregoff(ctxt, p.From3)
2062                 var mask [2]uint8
2063                 maskgen64(ctxt, p, mask[:], uint64(d))
2064                 if int32(mask[1]) != (63 - v) {
2065                         ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p)
2066                 }
2067                 o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
2068                 o1 |= (uint32(mask[0]) & 31) << 6
2069                 if v&0x20 != 0 {
2070                         o1 |= 1 << 1
2071                 }
2072                 if mask[0]&0x20 != 0 {
2073                         o1 |= 1 << 5 /* mb[5] is top bit */
2074                 }
2075
2076         case 31: /* dword */
2077                 d := vregoff(ctxt, &p.From)
2078
2079                 if ctxt.Arch.ByteOrder == binary.BigEndian {
2080                         o1 = uint32(d >> 32)
2081                         o2 = uint32(d)
2082                 } else {
2083                         o1 = uint32(d)
2084                         o2 = uint32(d >> 32)
2085                 }
2086
2087                 if p.From.Sym != nil {
2088                         rel := obj.Addrel(ctxt.Cursym)
2089                         rel.Off = int32(ctxt.Pc)
2090                         rel.Siz = 8
2091                         rel.Sym = p.From.Sym
2092                         rel.Add = p.From.Offset
2093                         rel.Type = obj.R_ADDR
2094                         o2 = 0
2095                         o1 = o2
2096                 }
2097
2098         case 32: /* fmul frc,fra,frd */
2099                 r := int(p.Reg)
2100
2101                 if r == 0 {
2102                         r = int(p.To.Reg)
2103                 }
2104                 o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), 0) | (uint32(p.From.Reg)&31)<<6
2105
2106         case 33: /* fabs [frb,]frd; fmr. frb,frd */
2107                 r := int(p.From.Reg)
2108
2109                 if oclass(&p.From) == C_NONE {
2110                         r = int(p.To.Reg)
2111                 }
2112                 o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), 0, uint32(r))
2113
2114         case 34: /* FMADDx fra,frb,frc,frd (d=a*b+c); FSELx a<0? (d=b): (d=c) */
2115                 o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg)) | (uint32(p.From3.Reg)&31)<<6
2116
2117         case 35: /* mov r,lext/lauto/loreg ==> cau $(v>>16),sb,r'; store o(r') */
2118                 v := regoff(ctxt, &p.To)
2119
2120                 r := int(p.To.Reg)
2121                 if r == 0 {
2122                         r = int(o.param)
2123                 }
2124                 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
2125                 o2 = AOP_IRR(opstore(ctxt, p.As), uint32(p.From.Reg), REGTMP, uint32(v))
2126
2127         case 36: /* mov bz/h/hz lext/lauto/lreg,r ==> lbz/lha/lhz etc */
2128                 v := regoff(ctxt, &p.From)
2129
2130                 r := int(p.From.Reg)
2131                 if r == 0 {
2132                         r = int(o.param)
2133                 }
2134                 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
2135                 o2 = AOP_IRR(opload(ctxt, p.As), uint32(p.To.Reg), REGTMP, uint32(v))
2136
2137         case 37: /* movb lext/lauto/lreg,r ==> lbz o(reg),r; extsb r */
2138                 v := regoff(ctxt, &p.From)
2139
2140                 r := int(p.From.Reg)
2141                 if r == 0 {
2142                         r = int(o.param)
2143                 }
2144                 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
2145                 o2 = AOP_IRR(opload(ctxt, p.As), uint32(p.To.Reg), REGTMP, uint32(v))
2146                 o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
2147
2148         case 40: /* word */
2149                 o1 = uint32(regoff(ctxt, &p.From))
2150
2151         case 41: /* stswi */
2152                 o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.From.Reg), uint32(p.To.Reg), 0) | (uint32(regoff(ctxt, p.From3))&0x7F)<<11
2153
2154         case 42: /* lswi */
2155                 o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Reg), 0) | (uint32(regoff(ctxt, p.From3))&0x7F)<<11
2156
2157         case 43: /* unary indexed source: dcbf (b); dcbf (a+b) */
2158                 o1 = AOP_RRR(oprrr(ctxt, p.As), 0, uint32(p.From.Index), uint32(p.From.Reg))
2159
2160         case 44: /* indexed store */
2161                 o1 = AOP_RRR(opstorex(ctxt, p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg))
2162
2163         case 45: /* indexed load */
2164                 o1 = AOP_RRR(oploadx(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
2165
2166         case 46: /* plain op */
2167                 o1 = oprrr(ctxt, p.As)
2168
2169         case 47: /* op Ra, Rd; also op [Ra,] Rd */
2170                 r := int(p.From.Reg)
2171
2172                 if r == 0 {
2173                         r = int(p.To.Reg)
2174                 }
2175                 o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), 0)
2176
2177         case 48: /* op Rs, Ra */
2178                 r := int(p.From.Reg)
2179
2180                 if r == 0 {
2181                         r = int(p.To.Reg)
2182                 }
2183                 o1 = LOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), 0)
2184
2185         case 49: /* op Rb; op $n, Rb */
2186                 if p.From.Type != obj.TYPE_REG { /* tlbie $L, rB */
2187                         v := regoff(ctxt, &p.From) & 1
2188                         o1 = AOP_RRR(oprrr(ctxt, p.As), 0, 0, uint32(p.To.Reg)) | uint32(v)<<21
2189                 } else {
2190                         o1 = AOP_RRR(oprrr(ctxt, p.As), 0, 0, uint32(p.From.Reg))
2191                 }
2192
2193         case 50: /* rem[u] r1[,r2],r3 */
2194                 r := int(p.Reg)
2195
2196                 if r == 0 {
2197                         r = int(p.To.Reg)
2198                 }
2199                 v := oprrr(ctxt, p.As)
2200                 t := v & (1<<10 | 1) /* OE|Rc */
2201                 o1 = AOP_RRR(v&^t, REGTMP, uint32(r), uint32(p.From.Reg))
2202                 o2 = AOP_RRR(OP_MULLW, REGTMP, REGTMP, uint32(p.From.Reg))
2203                 o3 = AOP_RRR(OP_SUBF|t, uint32(p.To.Reg), REGTMP, uint32(r))
2204                 if p.As == AREMU {
2205                         o4 = o3
2206
2207                         /* Clear top 32 bits */
2208                         o3 = OP_RLW(OP_RLDIC, REGTMP, REGTMP, 0, 0, 0) | 1<<5
2209                 }
2210
2211         case 51: /* remd[u] r1[,r2],r3 */
2212                 r := int(p.Reg)
2213
2214                 if r == 0 {
2215                         r = int(p.To.Reg)
2216                 }
2217                 v := oprrr(ctxt, p.As)
2218                 t := v & (1<<10 | 1) /* OE|Rc */
2219                 o1 = AOP_RRR(v&^t, REGTMP, uint32(r), uint32(p.From.Reg))
2220                 o2 = AOP_RRR(OP_MULLD, REGTMP, REGTMP, uint32(p.From.Reg))
2221                 o3 = AOP_RRR(OP_SUBF|t, uint32(p.To.Reg), REGTMP, uint32(r))
2222
2223         case 52: /* mtfsbNx cr(n) */
2224                 v := regoff(ctxt, &p.From) & 31
2225
2226                 o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(v), 0, 0)
2227
2228         case 53: /* mffsX ,fr1 */
2229                 o1 = AOP_RRR(OP_MFFS, uint32(p.To.Reg), 0, 0)
2230
2231         case 54: /* mov msr,r1; mov r1, msr*/
2232                 if oclass(&p.From) == C_REG {
2233                         if p.As == AMOVD {
2234                                 o1 = AOP_RRR(OP_MTMSRD, uint32(p.From.Reg), 0, 0)
2235                         } else {
2236                                 o1 = AOP_RRR(OP_MTMSR, uint32(p.From.Reg), 0, 0)
2237                         }
2238                 } else {
2239                         o1 = AOP_RRR(OP_MFMSR, uint32(p.To.Reg), 0, 0)
2240                 }
2241
2242         case 55: /* op Rb, Rd */
2243                 o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), 0, uint32(p.From.Reg))
2244
2245         case 56: /* sra $sh,[s,]a; srd $sh,[s,]a */
2246                 v := regoff(ctxt, &p.From)
2247
2248                 r := int(p.Reg)
2249                 if r == 0 {
2250                         r = int(p.To.Reg)
2251                 }
2252                 o1 = AOP_RRR(opirr(ctxt, p.As), uint32(r), uint32(p.To.Reg), uint32(v)&31)
2253                 if (p.As == ASRAD || p.As == ASRADCC) && (v&0x20 != 0) {
2254                         o1 |= 1 << 1 /* mb[5] */
2255                 }
2256
2257         case 57: /* slw $sh,[s,]a -> rlwinm ... */
2258                 v := regoff(ctxt, &p.From)
2259
2260                 r := int(p.Reg)
2261                 if r == 0 {
2262                         r = int(p.To.Reg)
2263                 }
2264
2265                 /*
2266                          * Let user (gs) shoot himself in the foot.
2267                          * qc has already complained.
2268                          *
2269                         if(v < 0 || v > 31)
2270                                 ctxt->diag("illegal shift %ld\n%v", v, p);
2271                 */
2272                 if v < 0 {
2273                         v = 0
2274                 } else if v > 32 {
2275                         v = 32
2276                 }
2277                 var mask [2]uint8
2278                 if p.As == ASRW || p.As == ASRWCC { /* shift right */
2279                         mask[0] = uint8(v)
2280                         mask[1] = 31
2281                         v = 32 - v
2282                 } else {
2283                         mask[0] = 0
2284                         mask[1] = uint8(31 - v)
2285                 }
2286
2287                 o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(r), uint32(v), uint32(mask[0]), uint32(mask[1]))
2288                 if p.As == ASLWCC || p.As == ASRWCC {
2289                         o1 |= 1 /* Rc */
2290                 }
2291
2292         case 58: /* logical $andcon,[s],a */
2293                 v := regoff(ctxt, &p.From)
2294
2295                 r := int(p.Reg)
2296                 if r == 0 {
2297                         r = int(p.To.Reg)
2298                 }
2299                 o1 = LOP_IRR(opirr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2300
2301         case 59: /* or/and $ucon,,r */
2302                 v := regoff(ctxt, &p.From)
2303
2304                 r := int(p.Reg)
2305                 if r == 0 {
2306                         r = int(p.To.Reg)
2307                 }
2308                 o1 = LOP_IRR(opirr(ctxt, -p.As), uint32(p.To.Reg), uint32(r), uint32(v)>>16) /* oris, xoris, andis */
2309
2310         case 60: /* tw to,a,b */
2311                 r := int(regoff(ctxt, &p.From) & 31)
2312
2313                 o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(r), uint32(p.Reg), uint32(p.To.Reg))
2314
2315         case 61: /* tw to,a,$simm */
2316                 r := int(regoff(ctxt, &p.From) & 31)
2317
2318                 v := regoff(ctxt, &p.To)
2319                 o1 = AOP_IRR(opirr(ctxt, p.As), uint32(r), uint32(p.Reg), uint32(v))
2320
2321         case 62: /* rlwmi $sh,s,$mask,a */
2322                 v := regoff(ctxt, &p.From)
2323
2324                 var mask [2]uint8
2325                 maskgen(ctxt, p, mask[:], uint32(regoff(ctxt, p.From3)))
2326                 o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(v))
2327                 o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
2328
2329         case 63: /* rlwmi b,s,$mask,a */
2330                 var mask [2]uint8
2331                 maskgen(ctxt, p, mask[:], uint32(regoff(ctxt, p.From3)))
2332
2333                 o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(p.From.Reg))
2334                 o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
2335
2336         case 64: /* mtfsf fr[, $m] {,fpcsr} */
2337                 var v int32
2338                 if p.From3Type() != obj.TYPE_NONE {
2339                         v = regoff(ctxt, p.From3) & 255
2340                 } else {
2341                         v = 255
2342                 }
2343                 o1 = OP_MTFSF | uint32(v)<<17 | uint32(p.From.Reg)<<11
2344
2345         case 65: /* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */
2346                 if p.To.Reg == 0 {
2347                         ctxt.Diag("must specify FPSCR(n)\n%v", p)
2348                 }
2349                 o1 = OP_MTFSFI | (uint32(p.To.Reg)&15)<<23 | (uint32(regoff(ctxt, &p.From))&31)<<12
2350
2351         case 66: /* mov spr,r1; mov r1,spr, also dcr */
2352                 var r int
2353                 var v int32
2354                 if REG_R0 <= p.From.Reg && p.From.Reg <= REG_R31 {
2355                         r = int(p.From.Reg)
2356                         v = int32(p.To.Reg)
2357                         if REG_DCR0 <= v && v <= REG_DCR0+1023 {
2358                                 o1 = OPVCC(31, 451, 0, 0) /* mtdcr */
2359                         } else {
2360                                 o1 = OPVCC(31, 467, 0, 0) /* mtspr */
2361                         }
2362                 } else {
2363                         r = int(p.To.Reg)
2364                         v = int32(p.From.Reg)
2365                         if REG_DCR0 <= v && v <= REG_DCR0+1023 {
2366                                 o1 = OPVCC(31, 323, 0, 0) /* mfdcr */
2367                         } else {
2368                                 o1 = OPVCC(31, 339, 0, 0) /* mfspr */
2369                         }
2370                 }
2371
2372                 o1 = AOP_RRR(o1, uint32(r), 0, 0) | (uint32(v)&0x1f)<<16 | ((uint32(v)>>5)&0x1f)<<11
2373
2374         case 67: /* mcrf crfD,crfS */
2375                 if p.From.Type != obj.TYPE_REG || p.From.Reg < REG_CR0 || REG_CR7 < p.From.Reg || p.To.Type != obj.TYPE_REG || p.To.Reg < REG_CR0 || REG_CR7 < p.To.Reg {
2376                         ctxt.Diag("illegal CR field number\n%v", p)
2377                 }
2378                 o1 = AOP_RRR(OP_MCRF, ((uint32(p.To.Reg) & 7) << 2), ((uint32(p.From.Reg) & 7) << 2), 0)
2379
2380         case 68: /* mfcr rD; mfocrf CRM,rD */
2381                 if p.From.Type == obj.TYPE_REG && REG_CR0 <= p.From.Reg && p.From.Reg <= REG_CR7 {
2382                         v := int32(1 << uint(7-(p.To.Reg&7)))                                 /* CR(n) */
2383                         o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) | 1<<20 | uint32(v)<<12 /* new form, mfocrf */
2384                 } else {
2385                         o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) /* old form, whole register */
2386                 }
2387
2388         case 69: /* mtcrf CRM,rS */
2389                 var v int32
2390                 if p.From3Type() != obj.TYPE_NONE {
2391                         if p.To.Reg != 0 {
2392                                 ctxt.Diag("can't use both mask and CR(n)\n%v", p)
2393                         }
2394                         v = regoff(ctxt, p.From3) & 0xff
2395                 } else {
2396                         if p.To.Reg == 0 {
2397                                 v = 0xff /* CR */
2398                         } else {
2399                                 v = 1 << uint(7-(p.To.Reg&7)) /* CR(n) */
2400                         }
2401                 }
2402
2403                 o1 = AOP_RRR(OP_MTCRF, uint32(p.From.Reg), 0, 0) | uint32(v)<<12
2404
2405         case 70: /* [f]cmp r,r,cr*/
2406                 var r int
2407                 if p.Reg == 0 {
2408                         r = 0
2409                 } else {
2410                         r = (int(p.Reg) & 7) << 2
2411                 }
2412                 o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg))
2413
2414         case 71: /* cmp[l] r,i,cr*/
2415                 var r int
2416                 if p.Reg == 0 {
2417                         r = 0
2418                 } else {
2419                         r = (int(p.Reg) & 7) << 2
2420                 }
2421                 o1 = AOP_RRR(opirr(ctxt, p.As), uint32(r), uint32(p.From.Reg), 0) | uint32(regoff(ctxt, &p.To))&0xffff
2422
2423         case 72: /* slbmte (Rb+Rs -> slb[Rb]) -> Rs, Rb */
2424                 o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.From.Reg), 0, uint32(p.To.Reg))
2425
2426         case 73: /* mcrfs crfD,crfS */
2427                 if p.From.Type != obj.TYPE_REG || p.From.Reg != REG_FPSCR || p.To.Type != obj.TYPE_REG || p.To.Reg < REG_CR0 || REG_CR7 < p.To.Reg {
2428                         ctxt.Diag("illegal FPSCR/CR field number\n%v", p)
2429                 }
2430                 o1 = AOP_RRR(OP_MCRFS, ((uint32(p.To.Reg) & 7) << 2), ((0 & 7) << 2), 0)
2431
2432         case 77: /* syscall $scon, syscall Rx */
2433                 if p.From.Type == obj.TYPE_CONST {
2434                         if p.From.Offset > BIG || p.From.Offset < -BIG {
2435                                 ctxt.Diag("illegal syscall, sysnum too large: %v", p)
2436                         }
2437                         o1 = AOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(p.From.Offset))
2438                 } else if p.From.Type == obj.TYPE_REG {
2439                         o1 = LOP_RRR(OP_OR, REGZERO, uint32(p.From.Reg), uint32(p.From.Reg))
2440                 } else {
2441                         ctxt.Diag("illegal syscall: %v", p)
2442                         o1 = 0x7fe00008 // trap always
2443                 }
2444
2445                 o2 = oprrr(ctxt, p.As)
2446                 o3 = AOP_RRR(oprrr(ctxt, AXOR), REGZERO, REGZERO, REGZERO) // XOR R0, R0
2447
2448         case 78: /* undef */
2449                 o1 = 0 /* "An instruction consisting entirely of binary 0s is guaranteed
2450                    always to be an illegal instruction."  */
2451
2452         /* relocation operations */
2453         case 74:
2454                 v := vregoff(ctxt, &p.To)
2455                 o1, o2 = symbolAccess(ctxt, p.To.Sym, v, p.From.Reg, opstore(ctxt, p.As))
2456
2457         //if(dlm) reloc(&p->to, p->pc, 1);
2458
2459         case 75:
2460                 v := vregoff(ctxt, &p.From)
2461                 o1, o2 = symbolAccess(ctxt, p.From.Sym, v, p.To.Reg, opload(ctxt, p.As))
2462
2463         //if(dlm) reloc(&p->from, p->pc, 1);
2464
2465         case 76:
2466                 v := vregoff(ctxt, &p.From)
2467                 o1, o2 = symbolAccess(ctxt, p.From.Sym, v, p.To.Reg, opload(ctxt, p.As))
2468                 o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
2469
2470                 //if(dlm) reloc(&p->from, p->pc, 1);
2471
2472         case 79:
2473                 if p.From.Offset != 0 {
2474                         ctxt.Diag("invalid offset against tls var %v", p)
2475                 }
2476                 o1 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGZERO, 0)
2477                 rel := obj.Addrel(ctxt.Cursym)
2478                 rel.Off = int32(ctxt.Pc)
2479                 rel.Siz = 4
2480                 rel.Sym = p.From.Sym
2481                 rel.Type = obj.R_POWER_TLS_LE
2482
2483         case 80:
2484                 if p.From.Offset != 0 {
2485                         ctxt.Diag("invalid offset against tls var %v", p)
2486                 }
2487                 o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
2488                 o2 = AOP_IRR(opload(ctxt, AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0)
2489                 rel := obj.Addrel(ctxt.Cursym)
2490                 rel.Off = int32(ctxt.Pc)
2491                 rel.Siz = 8
2492                 rel.Sym = p.From.Sym
2493                 rel.Type = obj.R_POWER_TLS_IE
2494
2495         case 81:
2496                 v := vregoff(ctxt, &p.To)
2497                 if v != 0 {
2498                         ctxt.Diag("invalid offset against GOT slot %v", p)
2499                 }
2500
2501                 o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
2502                 o2 = AOP_IRR(opload(ctxt, AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0)
2503                 rel := obj.Addrel(ctxt.Cursym)
2504                 rel.Off = int32(ctxt.Pc)
2505                 rel.Siz = 8
2506                 rel.Sym = p.From.Sym
2507                 rel.Type = obj.R_ADDRPOWER_GOT
2508         }
2509
2510         out[0] = o1
2511         out[1] = o2
2512         out[2] = o3
2513         out[3] = o4
2514         out[4] = o5
2515         return
2516 }
2517
2518 func vregoff(ctxt *obj.Link, a *obj.Addr) int64 {
2519         ctxt.Instoffset = 0
2520         if a != nil {
2521                 aclass(ctxt, a)
2522         }
2523         return ctxt.Instoffset
2524 }
2525
2526 func regoff(ctxt *obj.Link, a *obj.Addr) int32 {
2527         return int32(vregoff(ctxt, a))
2528 }
2529
2530 func oprrr(ctxt *obj.Link, a obj.As) uint32 {
2531         switch a {
2532         case AADD:
2533                 return OPVCC(31, 266, 0, 0)
2534         case AADDCC:
2535                 return OPVCC(31, 266, 0, 1)
2536         case AADDV:
2537                 return OPVCC(31, 266, 1, 0)
2538         case AADDVCC:
2539                 return OPVCC(31, 266, 1, 1)
2540         case AADDC:
2541                 return OPVCC(31, 10, 0, 0)
2542         case AADDCCC:
2543                 return OPVCC(31, 10, 0, 1)
2544         case AADDCV:
2545                 return OPVCC(31, 10, 1, 0)
2546         case AADDCVCC:
2547                 return OPVCC(31, 10, 1, 1)
2548         case AADDE:
2549                 return OPVCC(31, 138, 0, 0)
2550         case AADDECC:
2551                 return OPVCC(31, 138, 0, 1)
2552         case AADDEV:
2553                 return OPVCC(31, 138, 1, 0)
2554         case AADDEVCC:
2555                 return OPVCC(31, 138, 1, 1)
2556         case AADDME:
2557                 return OPVCC(31, 234, 0, 0)
2558         case AADDMECC:
2559                 return OPVCC(31, 234, 0, 1)
2560         case AADDMEV:
2561                 return OPVCC(31, 234, 1, 0)
2562         case AADDMEVCC:
2563                 return OPVCC(31, 234, 1, 1)
2564         case AADDZE:
2565                 return OPVCC(31, 202, 0, 0)
2566         case AADDZECC:
2567                 return OPVCC(31, 202, 0, 1)
2568         case AADDZEV:
2569                 return OPVCC(31, 202, 1, 0)
2570         case AADDZEVCC:
2571                 return OPVCC(31, 202, 1, 1)
2572
2573         case AAND:
2574                 return OPVCC(31, 28, 0, 0)
2575         case AANDCC:
2576                 return OPVCC(31, 28, 0, 1)
2577         case AANDN:
2578                 return OPVCC(31, 60, 0, 0)
2579         case AANDNCC:
2580                 return OPVCC(31, 60, 0, 1)
2581
2582         case ACMP:
2583                 return OPVCC(31, 0, 0, 0) | 1<<21 /* L=1 */
2584         case ACMPU:
2585                 return OPVCC(31, 32, 0, 0) | 1<<21
2586         case ACMPW:
2587                 return OPVCC(31, 0, 0, 0) /* L=0 */
2588         case ACMPWU:
2589                 return OPVCC(31, 32, 0, 0)
2590
2591         case ACNTLZW:
2592                 return OPVCC(31, 26, 0, 0)
2593         case ACNTLZWCC:
2594                 return OPVCC(31, 26, 0, 1)
2595         case ACNTLZD:
2596                 return OPVCC(31, 58, 0, 0)
2597         case ACNTLZDCC:
2598                 return OPVCC(31, 58, 0, 1)
2599
2600         case ACRAND:
2601                 return OPVCC(19, 257, 0, 0)
2602         case ACRANDN:
2603                 return OPVCC(19, 129, 0, 0)
2604         case ACREQV:
2605                 return OPVCC(19, 289, 0, 0)
2606         case ACRNAND:
2607                 return OPVCC(19, 225, 0, 0)
2608         case ACRNOR:
2609                 return OPVCC(19, 33, 0, 0)
2610         case ACROR:
2611                 return OPVCC(19, 449, 0, 0)
2612         case ACRORN:
2613                 return OPVCC(19, 417, 0, 0)
2614         case ACRXOR:
2615                 return OPVCC(19, 193, 0, 0)
2616
2617         case ADCBF:
2618                 return OPVCC(31, 86, 0, 0)
2619         case ADCBI:
2620                 return OPVCC(31, 470, 0, 0)
2621         case ADCBST:
2622                 return OPVCC(31, 54, 0, 0)
2623         case ADCBT:
2624                 return OPVCC(31, 278, 0, 0)
2625         case ADCBTST:
2626                 return OPVCC(31, 246, 0, 0)
2627         case ADCBZ:
2628                 return OPVCC(31, 1014, 0, 0)
2629
2630         case AREM, ADIVW:
2631                 return OPVCC(31, 491, 0, 0)
2632
2633         case AREMCC, ADIVWCC:
2634                 return OPVCC(31, 491, 0, 1)
2635
2636         case AREMV, ADIVWV:
2637                 return OPVCC(31, 491, 1, 0)
2638
2639         case AREMVCC, ADIVWVCC:
2640                 return OPVCC(31, 491, 1, 1)
2641
2642         case AREMU, ADIVWU:
2643                 return OPVCC(31, 459, 0, 0)
2644
2645         case AREMUCC, ADIVWUCC:
2646                 return OPVCC(31, 459, 0, 1)
2647
2648         case AREMUV, ADIVWUV:
2649                 return OPVCC(31, 459, 1, 0)
2650
2651         case AREMUVCC, ADIVWUVCC:
2652                 return OPVCC(31, 459, 1, 1)
2653
2654         case AREMD, ADIVD:
2655                 return OPVCC(31, 489, 0, 0)
2656
2657         case AREMDCC, ADIVDCC:
2658                 return OPVCC(31, 489, 0, 1)
2659
2660         case AREMDV, ADIVDV:
2661                 return OPVCC(31, 489, 1, 0)
2662
2663         case AREMDVCC, ADIVDVCC:
2664                 return OPVCC(31, 489, 1, 1)
2665
2666         case AREMDU, ADIVDU:
2667                 return OPVCC(31, 457, 0, 0)
2668
2669         case AREMDUCC, ADIVDUCC:
2670                 return OPVCC(31, 457, 0, 1)
2671
2672         case AREMDUV, ADIVDUV:
2673                 return OPVCC(31, 457, 1, 0)
2674
2675         case AREMDUVCC, ADIVDUVCC:
2676                 return OPVCC(31, 457, 1, 1)
2677
2678         case AEIEIO:
2679                 return OPVCC(31, 854, 0, 0)
2680
2681         case AEQV:
2682                 return OPVCC(31, 284, 0, 0)
2683         case AEQVCC:
2684                 return OPVCC(31, 284, 0, 1)
2685
2686         case AEXTSB:
2687                 return OPVCC(31, 954, 0, 0)
2688         case AEXTSBCC:
2689                 return OPVCC(31, 954, 0, 1)
2690         case AEXTSH:
2691                 return OPVCC(31, 922, 0, 0)
2692         case AEXTSHCC:
2693                 return OPVCC(31, 922, 0, 1)
2694         case AEXTSW:
2695                 return OPVCC(31, 986, 0, 0)
2696         case AEXTSWCC:
2697                 return OPVCC(31, 986, 0, 1)
2698
2699         case AFABS:
2700                 return OPVCC(63, 264, 0, 0)
2701         case AFABSCC:
2702                 return OPVCC(63, 264, 0, 1)
2703         case AFADD:
2704                 return OPVCC(63, 21, 0, 0)
2705         case AFADDCC:
2706                 return OPVCC(63, 21, 0, 1)
2707         case AFADDS:
2708                 return OPVCC(59, 21, 0, 0)
2709         case AFADDSCC:
2710                 return OPVCC(59, 21, 0, 1)
2711         case AFCMPO:
2712                 return OPVCC(63, 32, 0, 0)
2713         case AFCMPU:
2714                 return OPVCC(63, 0, 0, 0)
2715         case AFCFID:
2716                 return OPVCC(63, 846, 0, 0)
2717         case AFCFIDCC:
2718                 return OPVCC(63, 846, 0, 1)
2719         case AFCTIW:
2720                 return OPVCC(63, 14, 0, 0)
2721         case AFCTIWCC:
2722                 return OPVCC(63, 14, 0, 1)
2723         case AFCTIWZ:
2724                 return OPVCC(63, 15, 0, 0)
2725         case AFCTIWZCC:
2726                 return OPVCC(63, 15, 0, 1)
2727         case AFCTID:
2728                 return OPVCC(63, 814, 0, 0)
2729         case AFCTIDCC:
2730                 return OPVCC(63, 814, 0, 1)
2731         case AFCTIDZ:
2732                 return OPVCC(63, 815, 0, 0)
2733         case AFCTIDZCC:
2734                 return OPVCC(63, 815, 0, 1)
2735         case AFDIV:
2736                 return OPVCC(63, 18, 0, 0)
2737         case AFDIVCC:
2738                 return OPVCC(63, 18, 0, 1)
2739         case AFDIVS:
2740                 return OPVCC(59, 18, 0, 0)
2741         case AFDIVSCC:
2742                 return OPVCC(59, 18, 0, 1)
2743         case AFMADD:
2744                 return OPVCC(63, 29, 0, 0)
2745         case AFMADDCC:
2746                 return OPVCC(63, 29, 0, 1)
2747         case AFMADDS:
2748                 return OPVCC(59, 29, 0, 0)
2749         case AFMADDSCC:
2750                 return OPVCC(59, 29, 0, 1)
2751
2752         case AFMOVS, AFMOVD:
2753                 return OPVCC(63, 72, 0, 0) /* load */
2754         case AFMOVDCC:
2755                 return OPVCC(63, 72, 0, 1)
2756         case AFMSUB:
2757                 return OPVCC(63, 28, 0, 0)
2758         case AFMSUBCC:
2759                 return OPVCC(63, 28, 0, 1)
2760         case AFMSUBS:
2761                 return OPVCC(59, 28, 0, 0)
2762         case AFMSUBSCC:
2763                 return OPVCC(59, 28, 0, 1)
2764         case AFMUL:
2765                 return OPVCC(63, 25, 0, 0)
2766         case AFMULCC:
2767                 return OPVCC(63, 25, 0, 1)
2768         case AFMULS:
2769                 return OPVCC(59, 25, 0, 0)
2770         case AFMULSCC:
2771                 return OPVCC(59, 25, 0, 1)
2772         case AFNABS:
2773                 return OPVCC(63, 136, 0, 0)
2774         case AFNABSCC:
2775                 return OPVCC(63, 136, 0, 1)
2776         case AFNEG:
2777                 return OPVCC(63, 40, 0, 0)
2778         case AFNEGCC:
2779                 return OPVCC(63, 40, 0, 1)
2780         case AFNMADD:
2781                 return OPVCC(63, 31, 0, 0)
2782         case AFNMADDCC:
2783                 return OPVCC(63, 31, 0, 1)
2784         case AFNMADDS:
2785                 return OPVCC(59, 31, 0, 0)
2786         case AFNMADDSCC:
2787                 return OPVCC(59, 31, 0, 1)
2788         case AFNMSUB:
2789                 return OPVCC(63, 30, 0, 0)
2790         case AFNMSUBCC:
2791                 return OPVCC(63, 30, 0, 1)
2792         case AFNMSUBS:
2793                 return OPVCC(59, 30, 0, 0)
2794         case AFNMSUBSCC:
2795                 return OPVCC(59, 30, 0, 1)
2796         case AFRES:
2797                 return OPVCC(59, 24, 0, 0)
2798         case AFRESCC:
2799                 return OPVCC(59, 24, 0, 1)
2800         case AFRSP:
2801                 return OPVCC(63, 12, 0, 0)
2802         case AFRSPCC:
2803                 return OPVCC(63, 12, 0, 1)
2804         case AFRSQRTE:
2805                 return OPVCC(63, 26, 0, 0)
2806         case AFRSQRTECC:
2807                 return OPVCC(63, 26, 0, 1)
2808         case AFSEL:
2809                 return OPVCC(63, 23, 0, 0)
2810         case AFSELCC:
2811                 return OPVCC(63, 23, 0, 1)
2812         case AFSQRT:
2813                 return OPVCC(63, 22, 0, 0)
2814         case AFSQRTCC:
2815                 return OPVCC(63, 22, 0, 1)
2816         case AFSQRTS:
2817                 return OPVCC(59, 22, 0, 0)
2818         case AFSQRTSCC:
2819                 return OPVCC(59, 22, 0, 1)
2820         case AFSUB:
2821                 return OPVCC(63, 20, 0, 0)
2822         case AFSUBCC:
2823                 return OPVCC(63, 20, 0, 1)
2824         case AFSUBS:
2825                 return OPVCC(59, 20, 0, 0)
2826         case AFSUBSCC:
2827                 return OPVCC(59, 20, 0, 1)
2828
2829         case AICBI:
2830                 return OPVCC(31, 982, 0, 0)
2831         case AISYNC:
2832                 return OPVCC(19, 150, 0, 0)
2833
2834         case AMTFSB0:
2835                 return OPVCC(63, 70, 0, 0)
2836         case AMTFSB0CC:
2837                 return OPVCC(63, 70, 0, 1)
2838         case AMTFSB1:
2839                 return OPVCC(63, 38, 0, 0)
2840         case AMTFSB1CC:
2841                 return OPVCC(63, 38, 0, 1)
2842
2843         case AMULHW:
2844                 return OPVCC(31, 75, 0, 0)
2845         case AMULHWCC:
2846                 return OPVCC(31, 75, 0, 1)
2847         case AMULHWU:
2848                 return OPVCC(31, 11, 0, 0)
2849         case AMULHWUCC:
2850                 return OPVCC(31, 11, 0, 1)
2851         case AMULLW:
2852                 return OPVCC(31, 235, 0, 0)
2853         case AMULLWCC:
2854                 return OPVCC(31, 235, 0, 1)
2855         case AMULLWV:
2856                 return OPVCC(31, 235, 1, 0)
2857         case AMULLWVCC:
2858                 return OPVCC(31, 235, 1, 1)
2859
2860         case AMULHD:
2861                 return OPVCC(31, 73, 0, 0)
2862         case AMULHDCC:
2863                 return OPVCC(31, 73, 0, 1)
2864         case AMULHDU:
2865                 return OPVCC(31, 9, 0, 0)
2866         case AMULHDUCC:
2867                 return OPVCC(31, 9, 0, 1)
2868         case AMULLD:
2869                 return OPVCC(31, 233, 0, 0)
2870         case AMULLDCC:
2871                 return OPVCC(31, 233, 0, 1)
2872         case AMULLDV:
2873                 return OPVCC(31, 233, 1, 0)
2874         case AMULLDVCC:
2875                 return OPVCC(31, 233, 1, 1)
2876
2877         case ANAND:
2878                 return OPVCC(31, 476, 0, 0)
2879         case ANANDCC:
2880                 return OPVCC(31, 476, 0, 1)
2881         case ANEG:
2882                 return OPVCC(31, 104, 0, 0)
2883         case ANEGCC:
2884                 return OPVCC(31, 104, 0, 1)
2885         case ANEGV:
2886                 return OPVCC(31, 104, 1, 0)
2887         case ANEGVCC:
2888                 return OPVCC(31, 104, 1, 1)
2889         case ANOR:
2890                 return OPVCC(31, 124, 0, 0)
2891         case ANORCC:
2892                 return OPVCC(31, 124, 0, 1)
2893         case AOR:
2894                 return OPVCC(31, 444, 0, 0)
2895         case AORCC:
2896                 return OPVCC(31, 444, 0, 1)
2897         case AORN:
2898                 return OPVCC(31, 412, 0, 0)
2899         case AORNCC:
2900                 return OPVCC(31, 412, 0, 1)
2901
2902         case ARFI:
2903                 return OPVCC(19, 50, 0, 0)
2904         case ARFCI:
2905                 return OPVCC(19, 51, 0, 0)
2906         case ARFID:
2907                 return OPVCC(19, 18, 0, 0)
2908         case AHRFID:
2909                 return OPVCC(19, 274, 0, 0)
2910
2911         case ARLWMI:
2912                 return OPVCC(20, 0, 0, 0)
2913         case ARLWMICC:
2914                 return OPVCC(20, 0, 0, 1)
2915         case ARLWNM:
2916                 return OPVCC(23, 0, 0, 0)
2917         case ARLWNMCC:
2918                 return OPVCC(23, 0, 0, 1)
2919
2920         case ARLDCL:
2921                 return OPVCC(30, 8, 0, 0)
2922         case ARLDCR:
2923                 return OPVCC(30, 9, 0, 0)
2924
2925         case ASYSCALL:
2926                 return OPVCC(17, 1, 0, 0)
2927
2928         case ASLW:
2929                 return OPVCC(31, 24, 0, 0)
2930         case ASLWCC:
2931                 return OPVCC(31, 24, 0, 1)
2932         case ASLD:
2933                 return OPVCC(31, 27, 0, 0)
2934         case ASLDCC:
2935                 return OPVCC(31, 27, 0, 1)
2936
2937         case ASRAW:
2938                 return OPVCC(31, 792, 0, 0)
2939         case ASRAWCC:
2940                 return OPVCC(31, 792, 0, 1)
2941         case ASRAD:
2942                 return OPVCC(31, 794, 0, 0)
2943         case ASRADCC:
2944                 return OPVCC(31, 794, 0, 1)
2945
2946         case ASRW:
2947                 return OPVCC(31, 536, 0, 0)
2948         case ASRWCC:
2949                 return OPVCC(31, 536, 0, 1)
2950         case ASRD:
2951                 return OPVCC(31, 539, 0, 0)
2952         case ASRDCC:
2953                 return OPVCC(31, 539, 0, 1)
2954
2955         case ASUB:
2956                 return OPVCC(31, 40, 0, 0)
2957         case ASUBCC:
2958                 return OPVCC(31, 40, 0, 1)
2959         case ASUBV:
2960                 return OPVCC(31, 40, 1, 0)
2961         case ASUBVCC:
2962                 return OPVCC(31, 40, 1, 1)
2963         case ASUBC:
2964                 return OPVCC(31, 8, 0, 0)
2965         case ASUBCCC:
2966                 return OPVCC(31, 8, 0, 1)
2967         case ASUBCV:
2968                 return OPVCC(31, 8, 1, 0)
2969         case ASUBCVCC:
2970                 return OPVCC(31, 8, 1, 1)
2971         case ASUBE:
2972                 return OPVCC(31, 136, 0, 0)
2973         case ASUBECC:
2974                 return OPVCC(31, 136, 0, 1)
2975         case ASUBEV:
2976                 return OPVCC(31, 136, 1, 0)
2977         case ASUBEVCC:
2978                 return OPVCC(31, 136, 1, 1)
2979         case ASUBME:
2980                 return OPVCC(31, 232, 0, 0)
2981         case ASUBMECC:
2982                 return OPVCC(31, 232, 0, 1)
2983         case ASUBMEV:
2984                 return OPVCC(31, 232, 1, 0)
2985         case ASUBMEVCC:
2986                 return OPVCC(31, 232, 1, 1)
2987         case ASUBZE:
2988                 return OPVCC(31, 200, 0, 0)
2989         case ASUBZECC:
2990                 return OPVCC(31, 200, 0, 1)
2991         case ASUBZEV:
2992                 return OPVCC(31, 200, 1, 0)
2993         case ASUBZEVCC:
2994                 return OPVCC(31, 200, 1, 1)
2995
2996         case ASYNC:
2997                 return OPVCC(31, 598, 0, 0)
2998         case APTESYNC:
2999                 return OPVCC(31, 598, 0, 0) | 2<<21
3000
3001         case ATLBIE:
3002                 return OPVCC(31, 306, 0, 0)
3003         case ATLBIEL:
3004                 return OPVCC(31, 274, 0, 0)
3005         case ATLBSYNC:
3006                 return OPVCC(31, 566, 0, 0)
3007         case ASLBIA:
3008                 return OPVCC(31, 498, 0, 0)
3009         case ASLBIE:
3010                 return OPVCC(31, 434, 0, 0)
3011         case ASLBMFEE:
3012                 return OPVCC(31, 915, 0, 0)
3013         case ASLBMFEV:
3014                 return OPVCC(31, 851, 0, 0)
3015         case ASLBMTE:
3016                 return OPVCC(31, 402, 0, 0)
3017
3018         case ATW:
3019                 return OPVCC(31, 4, 0, 0)
3020         case ATD:
3021                 return OPVCC(31, 68, 0, 0)
3022
3023         case AXOR:
3024                 return OPVCC(31, 316, 0, 0)
3025         case AXORCC:
3026                 return OPVCC(31, 316, 0, 1)
3027         }
3028
3029         ctxt.Diag("bad r/r opcode %v", obj.Aconv(a))
3030         return 0
3031 }
3032
3033 func opirr(ctxt *obj.Link, a obj.As) uint32 {
3034         switch a {
3035         case AADD:
3036                 return OPVCC(14, 0, 0, 0)
3037         case AADDC:
3038                 return OPVCC(12, 0, 0, 0)
3039         case AADDCCC:
3040                 return OPVCC(13, 0, 0, 0)
3041         case -AADD:
3042                 return OPVCC(15, 0, 0, 0) /* ADDIS/CAU */
3043
3044         case AANDCC:
3045                 return OPVCC(28, 0, 0, 0)
3046         case -AANDCC:
3047                 return OPVCC(29, 0, 0, 0) /* ANDIS./ANDIU. */
3048
3049         case ABR:
3050                 return OPVCC(18, 0, 0, 0)
3051         case ABL:
3052                 return OPVCC(18, 0, 0, 0) | 1
3053         case obj.ADUFFZERO:
3054                 return OPVCC(18, 0, 0, 0) | 1
3055         case obj.ADUFFCOPY:
3056                 return OPVCC(18, 0, 0, 0) | 1
3057         case ABC:
3058                 return OPVCC(16, 0, 0, 0)
3059         case ABCL:
3060                 return OPVCC(16, 0, 0, 0) | 1
3061
3062         case ABEQ:
3063                 return AOP_RRR(16<<26, 12, 2, 0)
3064         case ABGE:
3065                 return AOP_RRR(16<<26, 4, 0, 0)
3066         case ABGT:
3067                 return AOP_RRR(16<<26, 12, 1, 0)
3068         case ABLE:
3069                 return AOP_RRR(16<<26, 4, 1, 0)
3070         case ABLT:
3071                 return AOP_RRR(16<<26, 12, 0, 0)
3072         case ABNE:
3073                 return AOP_RRR(16<<26, 4, 2, 0)
3074         case ABVC:
3075                 return AOP_RRR(16<<26, 4, 3, 0)
3076         case ABVS:
3077                 return AOP_RRR(16<<26, 12, 3, 0)
3078
3079         case ACMP:
3080                 return OPVCC(11, 0, 0, 0) | 1<<21 /* L=1 */
3081         case ACMPU:
3082                 return OPVCC(10, 0, 0, 0) | 1<<21
3083         case ACMPW:
3084                 return OPVCC(11, 0, 0, 0) /* L=0 */
3085         case ACMPWU:
3086                 return OPVCC(10, 0, 0, 0)
3087         case ALSW:
3088                 return OPVCC(31, 597, 0, 0)
3089
3090         case AMULLW:
3091                 return OPVCC(7, 0, 0, 0)
3092
3093         case AOR:
3094                 return OPVCC(24, 0, 0, 0)
3095         case -AOR:
3096                 return OPVCC(25, 0, 0, 0) /* ORIS/ORIU */
3097
3098         case ARLWMI:
3099                 return OPVCC(20, 0, 0, 0) /* rlwimi */
3100         case ARLWMICC:
3101                 return OPVCC(20, 0, 0, 1)
3102         case ARLDMI:
3103                 return OPVCC(30, 0, 0, 0) | 3<<2 /* rldimi */
3104         case ARLDMICC:
3105                 return OPVCC(30, 0, 0, 1) | 3<<2
3106
3107         case ARLWNM:
3108                 return OPVCC(21, 0, 0, 0) /* rlwinm */
3109         case ARLWNMCC:
3110                 return OPVCC(21, 0, 0, 1)
3111
3112         case ARLDCL:
3113                 return OPVCC(30, 0, 0, 0) /* rldicl */
3114         case ARLDCLCC:
3115                 return OPVCC(30, 0, 0, 1)
3116         case ARLDCR:
3117                 return OPVCC(30, 1, 0, 0) /* rldicr */
3118         case ARLDCRCC:
3119                 return OPVCC(30, 1, 0, 1)
3120         case ARLDC:
3121                 return OPVCC(30, 0, 0, 0) | 2<<2
3122         case ARLDCCC:
3123                 return OPVCC(30, 0, 0, 1) | 2<<2
3124
3125         case ASRAW:
3126                 return OPVCC(31, 824, 0, 0)
3127         case ASRAWCC:
3128                 return OPVCC(31, 824, 0, 1)
3129         case ASRAD:
3130                 return OPVCC(31, (413 << 1), 0, 0)
3131         case ASRADCC:
3132                 return OPVCC(31, (413 << 1), 0, 1)
3133
3134         case ASTSW:
3135                 return OPVCC(31, 725, 0, 0)
3136
3137         case ASUBC:
3138                 return OPVCC(8, 0, 0, 0)
3139
3140         case ATW:
3141                 return OPVCC(3, 0, 0, 0)
3142         case ATD:
3143                 return OPVCC(2, 0, 0, 0)
3144
3145         case AXOR:
3146                 return OPVCC(26, 0, 0, 0) /* XORIL */
3147         case -AXOR:
3148                 return OPVCC(27, 0, 0, 0) /* XORIU */
3149         }
3150
3151         ctxt.Diag("bad opcode i/r %v", obj.Aconv(a))
3152         return 0
3153 }
3154
3155 /*
3156  * load o(a),d
3157  */
3158 func opload(ctxt *obj.Link, a obj.As) uint32 {
3159         switch a {
3160         case AMOVD:
3161                 return OPVCC(58, 0, 0, 0) /* ld */
3162         case AMOVDU:
3163                 return OPVCC(58, 0, 0, 1) /* ldu */
3164         case AMOVWZ:
3165                 return OPVCC(32, 0, 0, 0) /* lwz */
3166         case AMOVWZU:
3167                 return OPVCC(33, 0, 0, 0) /* lwzu */
3168         case AMOVW:
3169                 return OPVCC(58, 0, 0, 0) | 1<<1 /* lwa */
3170
3171                 /* no AMOVWU */
3172         case AMOVB, AMOVBZ:
3173                 return OPVCC(34, 0, 0, 0)
3174                 /* load */
3175
3176         case AMOVBU, AMOVBZU:
3177                 return OPVCC(35, 0, 0, 0)
3178         case AFMOVD:
3179                 return OPVCC(50, 0, 0, 0)
3180         case AFMOVDU:
3181                 return OPVCC(51, 0, 0, 0)
3182         case AFMOVS:
3183                 return OPVCC(48, 0, 0, 0)
3184         case AFMOVSU:
3185                 return OPVCC(49, 0, 0, 0)
3186         case AMOVH:
3187                 return OPVCC(42, 0, 0, 0)
3188         case AMOVHU:
3189                 return OPVCC(43, 0, 0, 0)
3190         case AMOVHZ:
3191                 return OPVCC(40, 0, 0, 0)
3192         case AMOVHZU:
3193                 return OPVCC(41, 0, 0, 0)
3194         case AMOVMW:
3195                 return OPVCC(46, 0, 0, 0) /* lmw */
3196         }
3197
3198         ctxt.Diag("bad load opcode %v", obj.Aconv(a))
3199         return 0
3200 }
3201
3202 /*
3203  * indexed load a(b),d
3204  */
3205 func oploadx(ctxt *obj.Link, a obj.As) uint32 {
3206         switch a {
3207         case AMOVWZ:
3208                 return OPVCC(31, 23, 0, 0) /* lwzx */
3209         case AMOVWZU:
3210                 return OPVCC(31, 55, 0, 0) /* lwzux */
3211         case AMOVW:
3212                 return OPVCC(31, 341, 0, 0) /* lwax */
3213         case AMOVWU:
3214                 return OPVCC(31, 373, 0, 0) /* lwaux */
3215
3216         case AMOVB, AMOVBZ:
3217                 return OPVCC(31, 87, 0, 0) /* lbzx */
3218
3219         case AMOVBU, AMOVBZU:
3220                 return OPVCC(31, 119, 0, 0) /* lbzux */
3221         case AFMOVD:
3222                 return OPVCC(31, 599, 0, 0) /* lfdx */
3223         case AFMOVDU:
3224                 return OPVCC(31, 631, 0, 0) /*  lfdux */
3225         case AFMOVS:
3226                 return OPVCC(31, 535, 0, 0) /* lfsx */
3227         case AFMOVSU:
3228                 return OPVCC(31, 567, 0, 0) /* lfsux */
3229         case AMOVH:
3230                 return OPVCC(31, 343, 0, 0) /* lhax */
3231         case AMOVHU:
3232                 return OPVCC(31, 375, 0, 0) /* lhaux */
3233         case AMOVHBR:
3234                 return OPVCC(31, 790, 0, 0) /* lhbrx */
3235         case AMOVWBR:
3236                 return OPVCC(31, 534, 0, 0) /* lwbrx */
3237         case AMOVHZ:
3238                 return OPVCC(31, 279, 0, 0) /* lhzx */
3239         case AMOVHZU:
3240                 return OPVCC(31, 311, 0, 0) /* lhzux */
3241         case AECIWX:
3242                 return OPVCC(31, 310, 0, 0) /* eciwx */
3243         case ALWAR:
3244                 return OPVCC(31, 20, 0, 0) /* lwarx */
3245         case ALDAR:
3246                 return OPVCC(31, 84, 0, 0)
3247         case ALSW:
3248                 return OPVCC(31, 533, 0, 0) /* lswx */
3249         case AMOVD:
3250                 return OPVCC(31, 21, 0, 0) /* ldx */
3251         case AMOVDU:
3252                 return OPVCC(31, 53, 0, 0) /* ldux */
3253         }
3254
3255         ctxt.Diag("bad loadx opcode %v", obj.Aconv(a))
3256         return 0
3257 }
3258
3259 /*
3260  * store s,o(d)
3261  */
3262 func opstore(ctxt *obj.Link, a obj.As) uint32 {
3263         switch a {
3264         case AMOVB, AMOVBZ:
3265                 return OPVCC(38, 0, 0, 0) /* stb */
3266
3267         case AMOVBU, AMOVBZU:
3268                 return OPVCC(39, 0, 0, 0) /* stbu */
3269         case AFMOVD:
3270                 return OPVCC(54, 0, 0, 0) /* stfd */
3271         case AFMOVDU:
3272                 return OPVCC(55, 0, 0, 0) /* stfdu */
3273         case AFMOVS:
3274                 return OPVCC(52, 0, 0, 0) /* stfs */
3275         case AFMOVSU:
3276                 return OPVCC(53, 0, 0, 0) /* stfsu */
3277
3278         case AMOVHZ, AMOVH:
3279                 return OPVCC(44, 0, 0, 0) /* sth */
3280
3281         case AMOVHZU, AMOVHU:
3282                 return OPVCC(45, 0, 0, 0) /* sthu */
3283         case AMOVMW:
3284                 return OPVCC(47, 0, 0, 0) /* stmw */
3285         case ASTSW:
3286                 return OPVCC(31, 725, 0, 0) /* stswi */
3287
3288         case AMOVWZ, AMOVW:
3289                 return OPVCC(36, 0, 0, 0) /* stw */
3290
3291         case AMOVWZU, AMOVWU:
3292                 return OPVCC(37, 0, 0, 0) /* stwu */
3293         case AMOVD:
3294                 return OPVCC(62, 0, 0, 0) /* std */
3295         case AMOVDU:
3296                 return OPVCC(62, 0, 0, 1) /* stdu */
3297         }
3298
3299         ctxt.Diag("unknown store opcode %v", obj.Aconv(a))
3300         return 0
3301 }
3302
3303 /*
3304  * indexed store s,a(b)
3305  */
3306 func opstorex(ctxt *obj.Link, a obj.As) uint32 {
3307         switch a {
3308         case AMOVB, AMOVBZ:
3309                 return OPVCC(31, 215, 0, 0) /* stbx */
3310
3311         case AMOVBU, AMOVBZU:
3312                 return OPVCC(31, 247, 0, 0) /* stbux */
3313         case AFMOVD:
3314                 return OPVCC(31, 727, 0, 0) /* stfdx */
3315         case AFMOVDU:
3316                 return OPVCC(31, 759, 0, 0) /* stfdux */
3317         case AFMOVS:
3318                 return OPVCC(31, 663, 0, 0) /* stfsx */
3319         case AFMOVSU:
3320                 return OPVCC(31, 695, 0, 0) /* stfsux */
3321
3322         case AMOVHZ, AMOVH:
3323                 return OPVCC(31, 407, 0, 0) /* sthx */
3324         case AMOVHBR:
3325                 return OPVCC(31, 918, 0, 0) /* sthbrx */
3326
3327         case AMOVHZU, AMOVHU:
3328                 return OPVCC(31, 439, 0, 0) /* sthux */
3329
3330         case AMOVWZ, AMOVW:
3331                 return OPVCC(31, 151, 0, 0) /* stwx */
3332
3333         case AMOVWZU, AMOVWU:
3334                 return OPVCC(31, 183, 0, 0) /* stwux */
3335         case ASTSW:
3336                 return OPVCC(31, 661, 0, 0) /* stswx */
3337         case AMOVWBR:
3338                 return OPVCC(31, 662, 0, 0) /* stwbrx */
3339         case ASTWCCC:
3340                 return OPVCC(31, 150, 0, 1) /* stwcx. */
3341         case ASTDCCC:
3342                 return OPVCC(31, 214, 0, 1) /* stwdx. */
3343         case AECOWX:
3344                 return OPVCC(31, 438, 0, 0) /* ecowx */
3345         case AMOVD:
3346                 return OPVCC(31, 149, 0, 0) /* stdx */
3347         case AMOVDU:
3348                 return OPVCC(31, 181, 0, 0) /* stdux */
3349         }
3350
3351         ctxt.Diag("unknown storex opcode %v", obj.Aconv(a))
3352         return 0
3353 }