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, err := os.MkdirTemp("", "testpfxalign")
171 if err != nil {
172 t.Fatalf("could not create directory: %v", err)
173 }
174 defer os.RemoveAll(dir)
175
176 pgms := []struct {
177 text []byte
178 align string
179 hasNop bool
180 }{
181 {[]byte(x0pgm), "align=0x0", false},
182 {[]byte(x16pgm), "align=0x20", false},
183 {[]byte(x32pgm), "align=0x40", false},
184 {[]byte(x64pgm), "align=0x0", true},
185 {[]byte(x64pgmA64), "align=0x40", true},
186 {[]byte(x64pgmA32), "align=0x20", true},
187 }
188
189 for _, pgm := range pgms {
190 tmpfile := filepath.Join(dir, "x.s")
191 err = os.WriteFile(tmpfile, pgm.text, 0644)
192 if err != nil {
193 t.Fatalf("can't write output: %v\n", err)
194 }
195 cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-S", "-o", filepath.Join(dir, "test.o"), tmpfile)
196 cmd.Env = append(os.Environ(), "GOOS=linux", "GOARCH=ppc64le")
197 out, err := cmd.CombinedOutput()
198 if err != nil {
199 t.Errorf("Failed to compile %v: %v\n", pgm, err)
200 }
201 if !strings.Contains(string(out), pgm.align) {
202 t.Errorf("Fatal, misaligned text with prefixed instructions:\n%s", out)
203 }
204 hasNop := strings.Contains(string(out), "00 00 00 60")
205 if hasNop != pgm.hasNop {
206 t.Errorf("Fatal, prefixed instruction is missing nop padding:\n%s", out)
207 }
208 }
209 }
210
211
212
213
214 func TestLarge(t *testing.T) {
215 if testing.Short() {
216 t.Skip("Skip in short mode")
217 }
218 testenv.MustHaveGoBuild(t)
219
220 dir, err := os.MkdirTemp("", "testlarge")
221 if err != nil {
222 t.Fatalf("could not create directory: %v", err)
223 }
224 defer os.RemoveAll(dir)
225
226
227 tests := []struct {
228 jmpinsn string
229 backpattern []string
230 fwdpattern []string
231 }{
232
233
234
235
236 {"BEQ",
237 []string{``,
238 `0x20030 131120\s\(.*\)\tBC\t\$4,\sCR0EQ,\s131128`,
239 `0x20034 131124\s\(.*\)\tJMP\t0`},
240 []string{``,
241 `0x0000 00000\s\(.*\)\tBC\t\$4,\sCR0EQ,\s8`,
242 `0x0004 00004\s\(.*\)\tJMP\t131128`},
243 },
244 {"BNE",
245 []string{``,
246 `0x20030 131120\s\(.*\)\tBC\t\$12,\sCR0EQ,\s131128`,
247 `0x20034 131124\s\(.*\)\tJMP\t0`},
248 []string{``,
249 `0x0000 00000\s\(.*\)\tBC\t\$12,\sCR0EQ,\s8`,
250 `0x0004 00004\s\(.*\)\tJMP\t131128`}},
251
252 {"BC 16,0,",
253 []string{``,
254 `0x20030 131120\s\(.*\)\tBC\t\$18,\sCR0LT,\s131128`,
255 `0x20034 131124\s\(.*\)\tJMP\t0`},
256 []string{``,
257 `0x0000 00000\s\(.*\)\tBC\t\$18,\sCR0LT,\s8`,
258 `0x0004 00004\s\(.*\)\tJMP\t131128`}},
259 {"BC 18,0,",
260 []string{``,
261 `0x20030 131120\s\(.*\)\tBC\t\$16,\sCR0LT,\s131128`,
262 `0x20034 131124\s\(.*\)\tJMP\t0`},
263 []string{``,
264 `0x0000 00000\s\(.*\)\tBC\t\$16,\sCR0LT,\s8`,
265 `0x0004 00004\s\(.*\)\tJMP\t131128`}},
266
267 {"BC 8,0,",
268 []string{``,
269 `0x20034 131124\s\(.*\)\tBC\t\$8,\sCR0LT,\s131132`,
270 `0x20038 131128\s\(.*\)\tJMP\t131136`,
271 `0x2003c 131132\s\(.*\)\tJMP\t0\n`},
272 []string{``,
273 `0x0000 00000\s\(.*\)\tBC\t\$8,\sCR0LT,\s8`,
274 `0x0004 00004\s\(.*\)\tJMP\t12`,
275 `0x0008 00008\s\(.*\)\tJMP\t131136\n`}},
276 }
277
278 for _, test := range tests {
279
280 buf := bytes.NewBuffer(make([]byte, 0, 7000000))
281 gen(buf, test.jmpinsn)
282
283 tmpfile := filepath.Join(dir, "x.s")
284 err = os.WriteFile(tmpfile, buf.Bytes(), 0644)
285 if err != nil {
286 t.Fatalf("can't write output: %v\n", err)
287 }
288
289
290 for _, platenv := range platformEnvs {
291 cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-S", "-o", filepath.Join(dir, "test.o"), tmpfile)
292 cmd.Env = append(os.Environ(), platenv...)
293 out, err := cmd.CombinedOutput()
294 if err != nil {
295 t.Errorf("Assemble failed (%v): %v, output: %s", platenv, err, out)
296 }
297 matched, err := regexp.MatchString(strings.Join(test.fwdpattern, "\n\t*"), string(out))
298 if err != nil {
299 t.Fatal(err)
300 }
301 if !matched {
302 t.Errorf("Failed to detect long forward BC fixup in (%v):%s\n", platenv, out)
303 }
304 matched, err = regexp.MatchString(strings.Join(test.backpattern, "\n\t*"), string(out))
305 if err != nil {
306 t.Fatal(err)
307 }
308 if !matched {
309 t.Errorf("Failed to detect long backward BC fixup in (%v):%s\n", platenv, out)
310 }
311 }
312 }
313 }
314
315
316 func gen(buf *bytes.Buffer, jmpinsn string) {
317 fmt.Fprintln(buf, "TEXT f(SB),0,$0-0")
318 fmt.Fprintln(buf, "label_start:")
319 fmt.Fprintln(buf, jmpinsn, "label_end")
320 for i := 0; i < (1<<15 + 10); i++ {
321 fmt.Fprintln(buf, "MOVD R0, R1")
322 }
323 fmt.Fprintln(buf, jmpinsn, "label_start")
324 fmt.Fprintln(buf, "label_end:")
325 fmt.Fprintln(buf, "MOVD R0, R1")
326 fmt.Fprintln(buf, "RET")
327 }
328
329
330
331
332 func TestPCalign(t *testing.T) {
333 var pattern8 = `0x...8\s.*ADD\s..,\sR8`
334 var pattern16 = `0x...[80]\s.*MOVD\s..,\sR16`
335 var pattern32 = `0x...0\s.*ADD\s..,\sR3`
336
337 testenv.MustHaveGoBuild(t)
338
339 dir, err := os.MkdirTemp("", "testpcalign")
340 if err != nil {
341 t.Fatalf("could not create directory: %v", err)
342 }
343 defer os.RemoveAll(dir)
344
345
346
347 tmpfile := filepath.Join(dir, "x.s")
348 err = os.WriteFile(tmpfile, []byte(validPCAlignSrc), 0644)
349 if err != nil {
350 t.Fatalf("can't write output: %v\n", err)
351 }
352
353
354 cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), "-S", tmpfile)
355 cmd.Env = append(os.Environ(), "GOARCH=ppc64le", "GOOS=linux")
356 out, err := cmd.CombinedOutput()
357 if err != nil {
358 t.Errorf("Build failed: %v, output: %s", err, out)
359 }
360
361 matched, err := regexp.MatchString(pattern8, string(out))
362 if err != nil {
363 t.Fatal(err)
364 }
365 if !matched {
366 t.Errorf("The 8 byte alignment is not correct: %t, output:%s\n", matched, out)
367 }
368
369 matched, err = regexp.MatchString(pattern16, string(out))
370 if err != nil {
371 t.Fatal(err)
372 }
373 if !matched {
374 t.Errorf("The 16 byte alignment is not correct: %t, output:%s\n", matched, out)
375 }
376
377 matched, err = regexp.MatchString(pattern32, string(out))
378 if err != nil {
379 t.Fatal(err)
380 }
381 if !matched {
382 t.Errorf("The 32 byte alignment is not correct: %t, output:%s\n", matched, out)
383 }
384
385
386
387 tmpfile = filepath.Join(dir, "xi.s")
388 err = os.WriteFile(tmpfile, []byte(invalidPCAlignSrc), 0644)
389 if err != nil {
390 t.Fatalf("can't write output: %v\n", err)
391 }
392
393
394 cmd = testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "xi.o"), "-S", tmpfile)
395 cmd.Env = append(os.Environ(), "GOARCH=ppc64le", "GOOS=linux")
396 out, err = cmd.CombinedOutput()
397 if !strings.Contains(string(out), "Unexpected alignment") {
398 t.Errorf("Invalid alignment not detected for PCALIGN\n")
399 }
400 }
401
402
403
404
405
406
407
408
409
410
411
412
413
414 func TestRegValueAlignment(t *testing.T) {
415 tstFunc := func(rstart, rend, msk, rout int) {
416 for i := rstart; i <= rend; i++ {
417 if i&msk != rout {
418 t.Errorf("%v is not aligned to 0x%X (expected %d, got %d)\n", rconv(i), msk, rout, rstart&msk)
419 }
420 rout++
421 }
422 }
423 var testType = []struct {
424 rstart int
425 rend int
426 msk int
427 rout int
428 }{
429 {REG_VS0, REG_VS63, 63, 0},
430 {REG_R0, REG_R31, 31, 0},
431 {REG_F0, REG_F31, 31, 0},
432 {REG_V0, REG_V31, 31, 0},
433 {REG_V0, REG_V31, 63, 32},
434 {REG_F0, REG_F31, 63, 0},
435 {REG_SPR0, REG_SPR0 + 1023, 1023, 0},
436 {REG_CR0, REG_CR7, 7, 0},
437 {REG_CR0LT, REG_CR7SO, 31, 0},
438 }
439 for _, t := range testType {
440 tstFunc(t.rstart, t.rend, t.msk, t.rout)
441 }
442 }
443
444
445 func TestAddrClassifier(t *testing.T) {
446 type cmplx struct {
447 pic int
448 pic_dyn int
449 dyn int
450 nonpic int
451 }
452 tsts := [...]struct {
453 arg obj.Addr
454 output interface{}
455 }{
456
457 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_R1}, C_REG},
458 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_R2}, C_REGP},
459 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_F1}, C_FREG},
460 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_F2}, C_FREGP},
461 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_V2}, C_VREG},
462 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_VS1}, C_VSREG},
463 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_VS2}, C_VSREGP},
464 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_CR}, C_CREG},
465 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_CR1}, C_CREG},
466 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_CR1SO}, C_CRBIT},
467 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_SPR0}, C_SPR},
468 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_SPR0 + 8}, C_LR},
469 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_SPR0 + 9}, C_CTR},
470 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_FPSCR}, C_FPSCR},
471 {obj.Addr{Type: obj.TYPE_REG, Reg: REG_A1}, C_AREG},
472
473
474 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_GOTREF}, C_ADDR},
475 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_TOCREF}, C_ADDR},
476 {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}},
477 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: &obj.LSym{Type: objabi.SDATA}}, C_ADDR},
478 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_AUTO}, C_SOREG},
479 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_AUTO, Offset: BIG}, C_LOREG},
480 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_AUTO, Offset: -BIG - 1}, C_LOREG},
481 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_PARAM}, C_SOREG},
482 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_PARAM, Offset: BIG}, C_LOREG},
483 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_PARAM, Offset: -BIG - 33}, C_LOREG},
484 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE}, C_ZOREG},
485 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE, Index: REG_R4}, C_XOREG},
486 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE, Offset: 1}, C_SOREG},
487 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE, Offset: BIG}, C_LOREG},
488 {obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE, Offset: -BIG - 33}, C_LOREG},
489
490
491 {obj.Addr{Type: obj.TYPE_TEXTSIZE}, C_TEXTSIZE},
492 {obj.Addr{Type: obj.TYPE_FCONST, Val: 0.0}, C_ZCON},
493 {obj.Addr{Type: obj.TYPE_FCONST, Val: math.Float64frombits(0x8000000000000000)}, C_S16CON},
494
495
496 {obj.Addr{Type: obj.TYPE_ADDR, Reg: REG_R0, Name: obj.NAME_NONE, Offset: 1}, C_SACON},
497 {obj.Addr{Type: obj.TYPE_ADDR, Reg: REG_R0, Name: obj.NAME_NONE, Offset: BIG}, C_LACON},
498 {obj.Addr{Type: obj.TYPE_ADDR, Reg: REG_R0, Name: obj.NAME_NONE, Offset: -BIG - 1}, C_LACON},
499 {obj.Addr{Type: obj.TYPE_ADDR, Reg: REG_R0, Name: obj.NAME_NONE, Offset: 1 << 32}, C_DACON},
500 {obj.Addr{Type: obj.TYPE_ADDR, Name: obj.NAME_EXTERN, Sym: &obj.LSym{Type: objabi.SDATA}}, C_LACON},
501 {obj.Addr{Type: obj.TYPE_ADDR, Name: obj.NAME_STATIC, Sym: &obj.LSym{Type: objabi.SDATA}}, C_LACON},
502 {obj.Addr{Type: obj.TYPE_ADDR, Reg: REG_R0, Name: obj.NAME_AUTO, Offset: 1}, C_SACON},
503 {obj.Addr{Type: obj.TYPE_ADDR, Reg: REG_R0, Name: obj.NAME_AUTO, Offset: BIG}, C_LACON},
504 {obj.Addr{Type: obj.TYPE_ADDR, Reg: REG_R0, Name: obj.NAME_AUTO, Offset: -BIG - 1}, C_LACON},
505 {obj.Addr{Type: obj.TYPE_ADDR, Reg: REG_R0, Name: obj.NAME_PARAM, Offset: 1}, C_SACON},
506 {obj.Addr{Type: obj.TYPE_ADDR, Reg: REG_R0, Name: obj.NAME_PARAM, Offset: BIG}, C_LACON},
507 {obj.Addr{Type: obj.TYPE_ADDR, Reg: REG_R0, Name: obj.NAME_PARAM, Offset: -BIG - 33}, C_LACON},
508
509
510 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 0}, C_ZCON},
511 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 1}, C_U1CON},
512 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 2}, C_U2CON},
513 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 4}, C_U3CON},
514 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 8}, C_U4CON},
515 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 16}, C_U5CON},
516 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 32}, C_U8CON},
517 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 1 << 14}, C_U15CON},
518 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 1 << 15}, C_U16CON},
519 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 1 + 1<<16}, C_U31CON},
520 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 1 << 31}, C_U32CON},
521 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 1 << 32}, C_S34CON},
522 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 1 << 33}, C_64CON},
523 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: -1}, C_S16CON},
524 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: -0x10001}, C_S32CON},
525 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: 0x10001}, C_U31CON},
526 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: -(1 << 33)}, C_S34CON},
527 {obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: -(1 << 34)}, C_64CON},
528
529
530 {obj.Addr{Type: obj.TYPE_BRANCH, Sym: &obj.LSym{Type: objabi.SDATA}}, cmplx{C_BRA, C_BRAPIC, C_BRAPIC, C_BRA}},
531 {obj.Addr{Type: obj.TYPE_BRANCH}, C_BRA},
532 }
533
534 pic_ctxt9 := ctxt9{ctxt: &obj.Link{Flag_shared: true, Arch: &Linkppc64}, autosize: 0}
535 pic_dyn_ctxt9 := ctxt9{ctxt: &obj.Link{Flag_shared: true, Flag_dynlink: true, Arch: &Linkppc64}, autosize: 0}
536 dyn_ctxt9 := ctxt9{ctxt: &obj.Link{Flag_dynlink: true, Arch: &Linkppc64}, autosize: 0}
537 nonpic_ctxt9 := ctxt9{ctxt: &obj.Link{Arch: &Linkppc64}, autosize: 0}
538 ctxts := [...]*ctxt9{&pic_ctxt9, &pic_dyn_ctxt9, &dyn_ctxt9, &nonpic_ctxt9}
539 name := [...]string{"pic", "pic_dyn", "dyn", "nonpic"}
540 for _, tst := range tsts {
541 var expect []int
542 switch tst.output.(type) {
543 case cmplx:
544 v := tst.output.(cmplx)
545 expect = []int{v.pic, v.pic_dyn, v.dyn, v.nonpic}
546 case int:
547 expect = []int{tst.output.(int), tst.output.(int), tst.output.(int), tst.output.(int)}
548 }
549 for i := range ctxts {
550 if output := ctxts[i].aclass(&tst.arg); output != expect[i] {
551 t.Errorf("%s.aclass(%v) = %v, expected %v\n", name[i], tst.arg, DRconv(output), DRconv(expect[i]))
552 }
553 }
554 }
555 }
556
557
558 func TestOptabReinit(t *testing.T) {
559 buildcfg.GOOS = "linux"
560 buildcfg.GOARCH = "ppc64le"
561 buildcfg.GOPPC64 = 8
562 buildop(nil)
563 optabLen := len(optab)
564 buildcfg.GOPPC64 = 9
565 buildop(nil)
566 reinitOptabLen := len(optab)
567 if reinitOptabLen != optabLen {
568 t.Errorf("rerunning buildop changes optab size from %d to %d", optabLen, reinitOptabLen)
569 }
570 }
571
View as plain text