1
2
3
4
5 package ppc64
6
7 import (
8 "bytes"
9 "fmt"
10 "internal/buildcfg"
11 "internal/testenv"
12 "math"
13 "os"
14 "path/filepath"
15 "regexp"
16 "strings"
17 "testing"
18
19 "cmd/internal/obj"
20 "cmd/internal/objabi"
21 )
22
23 var platformEnvs = [][]string{
24 {"GOOS=aix", "GOARCH=ppc64"},
25 {"GOOS=linux", "GOARCH=ppc64"},
26 {"GOOS=linux", "GOARCH=ppc64le"},
27 }
28
29 const invalidPCAlignSrc = `
30 TEXT test(SB),0,$0-0
31 ADD $2, R3
32 PCALIGN $128
33 RET
34 `
35
36 const validPCAlignSrc = `
37 TEXT test(SB),0,$0-0
38 ADD $2, R3
39 PCALIGN $16
40 MOVD $8, R16
41 ADD $8, R4
42 PCALIGN $32
43 ADD $8, R3
44 PCALIGN $8
45 ADD $4, R8
46 RET
47 `
48
49 const x64pgm = `
50 TEXT test(SB),0,$0-0
51 OR R0, R0
52 OR R0, R0
53 OR R0, R0
54 OR R0, R0
55 OR R0, R0
56 OR R0, R0
57 OR R0, R0
58 OR R0, R0
59 OR R0, R0
60 OR R0, R0
61 OR R0, R0
62 OR R0, R0
63 OR R0, R0
64 OR R0, R0
65 OR R0, R0
66 PNOP
67 `
68 const x32pgm = `
69 TEXT test(SB),0,$0-0
70 OR R0, R0
71 OR R0, R0
72 OR R0, R0
73 OR R0, R0
74 OR R0, R0
75 OR R0, R0
76 OR R0, R0
77 PNOP
78 OR R0, R0
79 OR R0, R0
80 OR R0, R0
81 OR R0, R0
82 OR R0, R0
83 OR R0, R0
84 OR R0, R0
85 OR R0, R0
86 `
87
88 const x16pgm = `
89 TEXT test(SB),0,$0-0
90 OR R0, R0
91 OR R0, R0
92 OR R0, R0
93 PNOP
94 OR R0, R0
95 OR R0, R0
96 OR R0, R0
97 OR R0, R0
98 OR R0, R0
99 OR R0, R0
100 OR R0, R0
101 OR R0, R0
102 OR R0, R0
103 OR R0, R0
104 OR R0, R0
105 OR R0, R0
106 `
107
108 const x0pgm = `
109 TEXT test(SB),0,$0-0
110 OR R0, R0
111 OR R0, R0
112 OR R0, R0
113 OR R0, R0
114 PNOP
115 OR R0, R0
116 OR R0, R0
117 OR R0, R0
118 OR R0, R0
119 OR R0, R0
120 OR R0, R0
121 OR R0, R0
122 OR R0, R0
123 OR R0, R0
124 OR R0, R0
125 OR R0, R0
126 `
127 const x64pgmA64 = `
128 TEXT test(SB),0,$0-0
129 OR R0, R0
130 OR R0, R0
131 OR R0, R0
132 OR R0, R0
133 OR R0, R0
134 OR R0, R0
135 OR R0, R0
136 PNOP
137 OR R0, R0
138 OR R0, R0
139 OR R0, R0
140 OR R0, R0
141 OR R0, R0
142 OR R0, R0
143 PNOP
144 `
145
146 const x64pgmA32 = `
147 TEXT test(SB),0,$0-0
148 OR R0, R0
149 OR R0, R0
150 OR R0, R0
151 PNOP
152 OR R0, R0
153 OR R0, R0
154 OR R0, R0
155 OR R0, R0
156 OR R0, R0
157 OR R0, R0
158 OR R0, R0
159 OR R0, R0
160 OR R0, R0
161 OR R0, R0
162 PNOP
163 `
164
165
166
167 func TestPfxAlign(t *testing.T) {
168 testenv.MustHaveGoBuild(t)
169
170 dir := t.TempDir()
171
172 pgms := []struct {
173 text []byte
174 align string
175 hasNop bool
176 }{
177 {[]byte(x0pgm), "align=0x0", false},
178 {[]byte(x16pgm), "align=0x20", false},
179 {[]byte(x32pgm), "align=0x40", false},
180 {[]byte(x64pgm), "align=0x0", true},
181 {[]byte(x64pgmA64), "align=0x40", true},
182 {[]byte(x64pgmA32), "align=0x20", true},
183 }
184
185 for _, pgm := range pgms {
186 tmpfile := filepath.Join(dir, "x.s")
187 err := os.WriteFile(tmpfile, pgm.text, 0644)
188 if err != nil {
189 t.Fatalf("can't write output: %v\n", err)
190 }
191 cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-S", "-o", filepath.Join(dir, "test.o"), tmpfile)
192 cmd.Env = append(os.Environ(), "GOOS=linux", "GOARCH=ppc64le")
193 out, err := cmd.CombinedOutput()
194 if err != nil {
195 t.Errorf("Failed to compile %v: %v\n", pgm, err)
196 }
197 if !strings.Contains(string(out), pgm.align) {
198 t.Errorf("Fatal, misaligned text with prefixed instructions:\n%s", out)
199 }
200 hasNop := strings.Contains(string(out), "00 00 00 60")
201 if hasNop != pgm.hasNop {
202 t.Errorf("Fatal, prefixed instruction is missing nop padding:\n%s", out)
203 }
204 }
205 }
206
207
208
209
210 func TestLarge(t *testing.T) {
211 if testing.Short() {
212 t.Skip("Skip in short mode")
213 }
214 testenv.MustHaveGoBuild(t)
215
216 dir := t.TempDir()
217
218
219 tests := []struct {
220 jmpinsn string
221 backpattern []string
222 fwdpattern []string
223 }{
224
225
226
227
228 {"BEQ",
229 []string{``,
230 `0x20030 131120\s\(.*\)\tBC\t\$4,\sCR0EQ,\s131128`,
231 `0x20034 131124\s\(.*\)\tJMP\t0`},
232 []string{``,
233 `0x0000 00000\s\(.*\)\tBC\t\$4,\sCR0EQ,\s8`,
234 `0x0004 00004\s\(.*\)\tJMP\t131128`},
235 },
236 {"BNE",
237 []string{``,
238 `0x20030 131120\s\(.*\)\tBC\t\$12,\sCR0EQ,\s131128`,
239 `0x20034 131124\s\(.*\)\tJMP\t0`},
240 []string{``,
241 `0x0000 00000\s\(.*\)\tBC\t\$12,\sCR0EQ,\s8`,
242 `0x0004 00004\s\(.*\)\tJMP\t131128`}},
243
244 {"BC 16,0,",
245 []string{``,
246 `0x20030 131120\s\(.*\)\tBC\t\$18,\sCR0LT,\s131128`,
247 `0x20034 131124\s\(.*\)\tJMP\t0`},
248 []string{``,
249 `0x0000 00000\s\(.*\)\tBC\t\$18,\sCR0LT,\s8`,
250 `0x0004 00004\s\(.*\)\tJMP\t131128`}},
251 {"BC 18,0,",
252 []string{``,
253 `0x20030 131120\s\(.*\)\tBC\t\$16,\sCR0LT,\s131128`,
254 `0x20034 131124\s\(.*\)\tJMP\t0`},
255 []string{``,
256 `0x0000 00000\s\(.*\)\tBC\t\$16,\sCR0LT,\s8`,
257 `0x0004 00004\s\(.*\)\tJMP\t131128`}},
258
259 {"BC 8,0,",
260 []string{``,
261 `0x20034 131124\s\(.*\)\tBC\t\$8,\sCR0LT,\s131132`,
262 `0x20038 131128\s\(.*\)\tJMP\t131136`,
263 `0x2003c 131132\s\(.*\)\tJMP\t0\n`},
264 []string{``,
265 `0x0000 00000\s\(.*\)\tBC\t\$8,\sCR0LT,\s8`,
266 `0x0004 00004\s\(.*\)\tJMP\t12`,
267 `0x0008 00008\s\(.*\)\tJMP\t131136\n`}},
268 }
269
270 for _, test := range tests {
271
272 buf := bytes.NewBuffer(make([]byte, 0, 7000000))
273 gen(buf, test.jmpinsn)
274
275 tmpfile := filepath.Join(dir, "x.s")
276 err := os.WriteFile(tmpfile, buf.Bytes(), 0644)
277 if err != nil {
278 t.Fatalf("can't write output: %v\n", err)
279 }
280
281
282 for _, platenv := range platformEnvs {
283 cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-S", "-o", filepath.Join(dir, "test.o"), tmpfile)
284 cmd.Env = append(os.Environ(), platenv...)
285 out, err := cmd.CombinedOutput()
286 if err != nil {
287 t.Errorf("Assemble failed (%v): %v, output: %s", platenv, err, out)
288 }
289 matched, err := regexp.MatchString(strings.Join(test.fwdpattern, "\n\t*"), string(out))
290 if err != nil {
291 t.Fatal(err)
292 }
293 if !matched {
294 t.Errorf("Failed to detect long forward BC fixup in (%v):%s\n", platenv, out)
295 }
296 matched, err = regexp.MatchString(strings.Join(test.backpattern, "\n\t*"), string(out))
297 if err != nil {
298 t.Fatal(err)
299 }
300 if !matched {
301 t.Errorf("Failed to detect long backward BC fixup in (%v):%s\n", platenv, out)
302 }
303 }
304 }
305 }
306
307
308 func gen(buf *bytes.Buffer, jmpinsn string) {
309 fmt.Fprintln(buf, "TEXT f(SB),0,$0-0")
310 fmt.Fprintln(buf, "label_start:")
311 fmt.Fprintln(buf, jmpinsn, "label_end")
312 for i := 0; i < (1<<15 + 10); i++ {
313 fmt.Fprintln(buf, "MOVD R0, R1")
314 }
315 fmt.Fprintln(buf, jmpinsn, "label_start")
316 fmt.Fprintln(buf, "label_end:")
317 fmt.Fprintln(buf, "MOVD R0, R1")
318 fmt.Fprintln(buf, "RET")
319 }
320
321
322
323
324 func TestPCalign(t *testing.T) {
325 var pattern8 = `0x...8\s.*ADD\s..,\sR8`
326 var pattern16 = `0x...[80]\s.*MOVD\s..,\sR16`
327 var pattern32 = `0x...0\s.*ADD\s..,\sR3`
328
329 testenv.MustHaveGoBuild(t)
330
331 dir := t.TempDir()
332
333
334
335 tmpfile := filepath.Join(dir, "x.s")
336 err := os.WriteFile(tmpfile, []byte(validPCAlignSrc), 0644)
337 if err != nil {
338 t.Fatalf("can't write output: %v\n", err)
339 }
340
341
342 cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), "-S", tmpfile)
343 cmd.Env = append(os.Environ(), "GOARCH=ppc64le", "GOOS=linux")
344 out, err := cmd.CombinedOutput()
345 if err != nil {
346 t.Errorf("Build failed: %v, output: %s", err, out)
347 }
348
349 matched, err := regexp.MatchString(pattern8, string(out))
350 if err != nil {
351 t.Fatal(err)
352 }
353 if !matched {
354 t.Errorf("The 8 byte alignment is not correct: %t, output:%s\n", matched, out)
355 }
356
357 matched, err = regexp.MatchString(pattern16, string(out))
358 if err != nil {
359 t.Fatal(err)
360 }
361 if !matched {
362 t.Errorf("The 16 byte alignment is not correct: %t, output:%s\n", matched, out)
363 }
364
365 matched, err = regexp.MatchString(pattern32, string(out))
366 if err != nil {
367 t.Fatal(err)
368 }
369 if !matched {
370 t.Errorf("The 32 byte alignment is not correct: %t, output:%s\n", matched, out)
371 }
372
373
374
375 tmpfile = filepath.Join(dir, "xi.s")
376 err = os.WriteFile(tmpfile, []byte(invalidPCAlignSrc), 0644)
377 if err != nil {
378 t.Fatalf("can't write output: %v\n", err)
379 }
380
381
382 cmd = testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "xi.o"), "-S", tmpfile)
383 cmd.Env = append(os.Environ(), "GOARCH=ppc64le", "GOOS=linux")
384 out, err = cmd.CombinedOutput()
385 if !strings.Contains(string(out), "Unexpected alignment") {
386 t.Errorf("Invalid alignment not detected for PCALIGN\n")
387 }
388 }
389
390
391
392
393
394
395
396
397
398
399
400
401
402 func TestRegValueAlignment(t *testing.T) {
403 tstFunc := func(rstart, rend, msk, rout int) {
404 for i := rstart; i <= rend; i++ {
405 if i&msk != rout {
406 t.Errorf("%v is not aligned to 0x%X (expected %d, got %d)\n", rconv(i), msk, rout, rstart&msk)
407 }
408 rout++
409 }
410 }
411 var testType = []struct {
412 rstart int
413 rend int
414 msk int
415 rout int
416 }{
417 {REG_VS0, REG_VS63, 63, 0},
418 {REG_R0, REG_R31, 31, 0},
419 {REG_F0, REG_F31, 31, 0},
420 {REG_V0, REG_V31, 31, 0},
421 {REG_V0, REG_V31, 63, 32},
422 {REG_F0, REG_F31, 63, 0},
423 {REG_SPR0, REG_SPR0 + 1023, 1023, 0},
424 {REG_CR0, REG_CR7, 7, 0},
425 {REG_CR0LT, REG_CR7SO, 31, 0},
426 }
427 for _, t := range testType {
428 tstFunc(t.rstart, t.rend, t.msk, t.rout)
429 }
430 }
431
432
433 func TestAddrClassifier(t *testing.T) {
434 type cmplx struct {
435 pic int
436 pic_dyn int
437 dyn int
438 nonpic int
439 }
440 tsts := [...]struct {
441 arg obj.Addr
442 output interface{}
443 }{
444
445 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_R1}, C_REG},
446 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_R2}, C_REGP},
447 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_F1}, C_FREG},
448 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_F2}, C_FREGP},
449 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_V2}, C_VREG},
450 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_VS1}, C_VSREG},
451 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_VS2}, C_VSREGP},
452 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_CR}, C_CREG},
453 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_CR1}, C_CREG},
454 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_CR1SO}, C_CRBIT},
455 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_SPR0}, C_SPR},
456 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_SPR0 + 8}, C_LR},
457 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_SPR0 + 9}, C_CTR},
458 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_FPSCR}, C_FPSCR},
459 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_A1}, C_AREG},
460
461
462 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_GOTREF}, C_ADDR},
463 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_TOCREF}, C_ADDR},
464 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: &obj.LSym{Type: objabi.STLSBSS}}, cmplx{C_TLS_IE, C_TLS_IE, C_TLS_LE, C_TLS_LE}},
465 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: &obj.LSym{Type: objabi.SDATA}}, C_ADDR},
466 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_AUTO}, C_SOREG},
467 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_AUTO, Offset: BIG}, C_LOREG},
468 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_AUTO, Offset: -BIG - 1}, C_LOREG},
469 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_PARAM}, C_SOREG},
470 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_PARAM, Offset: BIG}, C_LOREG},
471 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_PARAM, Offset: -BIG - 33}, C_LOREG},
472 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE}, C_ZOREG},
473 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE, Index: REG_R4}, C_XOREG},
474 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE, Offset: 1}, C_SOREG},
475 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE, Offset: BIG}, C_LOREG},
476 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE, Offset: -BIG - 33}, C_LOREG},
477
478
479 {obj.Addr{Type: obj.TYPE_TEXTSIZE}, C_TEXTSIZE},
480 {obj.Addr{Type: obj.TYPE_FCONST, Val: 0.0}, C_ZCON},
481 {obj.Addr{Type: obj.TYPE_FCONST, Val: math.Float64frombits(0x8000000000000000)}, C_S16CON},
482
483
484 {obj.Addr{Type: obj.TYPE_ADDR, Reg: REG_R0, Name: obj.NAME_NONE, Offset: 1}, C_SACON},
485 {obj.Addr{Type: obj.TYPE_ADDR, Reg: REG_R0, Name: obj.NAME_NONE, Offset: BIG}, C_LACON},
486 {obj.Addr{Type: obj.TYPE_ADDR, Reg: REG_R0, Name: obj.NAME_NONE, Offset: -BIG - 1}, C_LACON},
487 {obj.Addr{Type: obj.TYPE_ADDR, Reg: REG_R0, Name: obj.NAME_NONE, Offset: 1 << 32}, C_DACON},
488 {obj.Addr{Type: obj.TYPE_ADDR, Name: obj.NAME_EXTERN, Sym: &obj.LSym{Type: objabi.SDATA}}, C_LACON},
489 {obj.Addr{Type: obj.TYPE_ADDR, Name: obj.NAME_STATIC, Sym: &obj.LSym{Type: objabi.SDATA}}, C_LACON},
490 {obj.Addr{Type: obj.TYPE_ADDR, Reg: REG_R0, Name: obj.NAME_AUTO, Offset: 1}, C_SACON},
491 {obj.Addr{Type: obj.TYPE_ADDR, Reg: REG_R0, Name: obj.NAME_AUTO, Offset: BIG}, C_LACON},
492 {obj.Addr{Type: obj.TYPE_ADDR, Reg: REG_R0, Name: obj.NAME_AUTO, Offset: -BIG - 1}, C_LACON},
493 {obj.Addr{Type: obj.TYPE_ADDR, Reg: REG_R0, Name: obj.NAME_PARAM, Offset: 1}, C_SACON},
494 {obj.Addr{Type: obj.TYPE_ADDR, Reg: REG_R0, Name: obj.NAME_PARAM, Offset: BIG}, C_LACON},
495 {obj.Addr{Type: obj.TYPE_ADDR, Reg: REG_R0, Name: obj.NAME_PARAM, Offset: -BIG - 33}, C_LACON},
496
497
498 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 0}, C_ZCON},
499 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 1}, C_U1CON},
500 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 2}, C_U2CON},
501 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 4}, C_U3CON},
502 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 8}, C_U4CON},
503 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 16}, C_U5CON},
504 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 32}, C_U8CON},
505 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 1 << 14}, C_U15CON},
506 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 1 << 15}, C_U16CON},
507 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 1 + 1<<16}, C_U31CON},
508 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 1 << 31}, C_U32CON},
509 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 1 << 32}, C_S34CON},
510 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 1 << 33}, C_64CON},
511 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: -1}, C_S16CON},
512 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: -0x10001}, C_S32CON},
513 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 0x10001}, C_U31CON},
514 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: -(1 << 33)}, C_S34CON},
515 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: -(1 << 34)}, C_64CON},
516
517
518 {obj.Addr{Type: obj.TYPE_BRANCH, Sym: &obj.LSym{Type: objabi.SDATA}}, cmplx{C_BRA, C_BRAPIC, C_BRAPIC, C_BRA}},
519 {obj.Addr{Type: obj.TYPE_BRANCH}, C_BRA},
520 }
521
522 pic_ctxt9 := ctxt9{ctxt: &obj.Link{Flag_shared: true, Arch: &Linkppc64}, autosize: 0}
523 pic_dyn_ctxt9 := ctxt9{ctxt: &obj.Link{Flag_shared: true, Flag_dynlink: true, Arch: &Linkppc64}, autosize: 0}
524 dyn_ctxt9 := ctxt9{ctxt: &obj.Link{Flag_dynlink: true, Arch: &Linkppc64}, autosize: 0}
525 nonpic_ctxt9 := ctxt9{ctxt: &obj.Link{Arch: &Linkppc64}, autosize: 0}
526 ctxts := [...]*ctxt9{&pic_ctxt9, &pic_dyn_ctxt9, &dyn_ctxt9, &nonpic_ctxt9}
527 name := [...]string{"pic", "pic_dyn", "dyn", "nonpic"}
528 for _, tst := range tsts {
529 var expect []int
530 switch tst.output.(type) {
531 case cmplx:
532 v := tst.output.(cmplx)
533 expect = []int{v.pic, v.pic_dyn, v.dyn, v.nonpic}
534 case int:
535 expect = []int{tst.output.(int), tst.output.(int), tst.output.(int), tst.output.(int)}
536 }
537 for i := range ctxts {
538 if output := ctxts[i].aclass(&tst.arg); output != expect[i] {
539 t.Errorf("%s.aclass(%v) = %v, expected %v\n", name[i], tst.arg, DRconv(output), DRconv(expect[i]))
540 }
541 }
542 }
543 }
544
545
546 func TestOptabReinit(t *testing.T) {
547 buildcfg.GOOS = "linux"
548 buildcfg.GOARCH = "ppc64le"
549 buildcfg.GOPPC64 = 8
550 buildop(nil)
551 optabLen := len(optab)
552 buildcfg.GOPPC64 = 9
553 buildop(nil)
554 reinitOptabLen := len(optab)
555 if reinitOptabLen != optabLen {
556 t.Errorf("rerunning buildop changes optab size from %d to %d", optabLen, reinitOptabLen)
557 }
558 }
559
View as plain text