src/cmd/asm/internal/asm/operand_test.go GO 1,035 lines View on github.com → Search inside
1// Copyright 2015 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.45package asm67import (8	"internal/buildcfg"9	"strings"10	"testing"1112	"cmd/asm/internal/arch"13	"cmd/asm/internal/lex"14	"cmd/internal/obj"15)1617// A simple in-out test: Do we print what we parse?1819func setArch(goarch string) (*arch.Arch, *obj.Link) {20	buildcfg.GOOS = "linux" // obj can handle this OS for all architectures.21	buildcfg.GOARCH = goarch22	architecture := arch.Set(goarch, false)23	if architecture == nil {24		panic("asm: unrecognized architecture " + goarch)25	}26	ctxt := obj.Linknew(architecture.LinkArch)27	ctxt.Pkgpath = "pkg"28	return architecture, ctxt29}3031func newParser(goarch string) *Parser {32	architecture, ctxt := setArch(goarch)33	return NewParser(ctxt, architecture, nil)34}3536// tryParse executes parse func in panicOnError=true context.37// parse is expected to call any parsing methods that may panic.38// Returns error gathered from recover; nil if no parse errors occurred.39//40// For unexpected panics, calls t.Fatal.41func tryParse(t *testing.T, parse func()) (err error) {42	panicOnError = true43	defer func() {44		panicOnError = false4546		e := recover()47		var ok bool48		if err, ok = e.(error); e != nil && !ok {49			t.Fatal(e)50		}51	}()5253	parse()5455	return nil56}5758func testBadOperandParser(t *testing.T, parser *Parser, tests []badOperandTest) {59	for _, test := range tests {60		err := tryParse(t, func() {61			parser.start(lex.Tokenize(test.input))62			addr := obj.Addr{}63			parser.operand(&addr)64		})6566		switch {67		case err == nil:68			t.Errorf("fail at %s: got no errors; expected %s\n", test.input, test.error)69		case !strings.Contains(err.Error(), test.error):70			t.Errorf("fail at %s: got %s; expected %s", test.input, err, test.error)71		}72	}73}7475func testOperandParser(t *testing.T, parser *Parser, tests []operandTest) {76	for _, test := range tests {77		parser.start(lex.Tokenize(test.input))78		addr := obj.Addr{}79		parser.operand(&addr)80		var result string81		if parser.allowABI {82			result = obj.DconvWithABIDetail(&emptyProg, &addr)83		} else {84			result = obj.Dconv(&emptyProg, &addr)85		}86		if result != test.output {87			t.Errorf("fail at %s: got %s; expected %s\n", test.input, result, test.output)88		}89	}90}9192func TestAMD64OperandParser(t *testing.T) {93	parser := newParser("amd64")94	testOperandParser(t, parser, amd64OperandTests)95	testBadOperandParser(t, parser, amd64BadOperandTests)96	parser.allowABI = true97	testOperandParser(t, parser, amd64RuntimeOperandTests)98	testBadOperandParser(t, parser, amd64BadOperandRuntimeTests)99}100101func Test386OperandParser(t *testing.T) {102	parser := newParser("386")103	testOperandParser(t, parser, x86OperandTests)104}105106func TestARMOperandParser(t *testing.T) {107	parser := newParser("arm")108	testOperandParser(t, parser, armOperandTests)109}110func TestARM64OperandParser(t *testing.T) {111	parser := newParser("arm64")112	testOperandParser(t, parser, arm64OperandTests)113}114115func TestPPC64OperandParser(t *testing.T) {116	parser := newParser("ppc64")117	testOperandParser(t, parser, ppc64OperandTests)118}119120func TestMIPSOperandParser(t *testing.T) {121	parser := newParser("mips")122	testOperandParser(t, parser, mipsOperandTests)123}124125func TestMIPS64OperandParser(t *testing.T) {126	parser := newParser("mips64")127	testOperandParser(t, parser, mips64OperandTests)128}129130func TestLOONG64OperandParser(t *testing.T) {131	parser := newParser("loong64")132	testOperandParser(t, parser, loong64OperandTests)133}134135func TestS390XOperandParser(t *testing.T) {136	parser := newParser("s390x")137	testOperandParser(t, parser, s390xOperandTests)138}139140func TestFuncAddress(t *testing.T) {141	type subtest struct {142		arch  string143		tests []operandTest144	}145	for _, sub := range []subtest{146		{"amd64", amd64OperandTests},147		{"386", x86OperandTests},148		{"arm", armOperandTests},149		{"arm64", arm64OperandTests},150		{"ppc64", ppc64OperandTests},151		{"mips", mipsOperandTests},152		{"mips64", mips64OperandTests},153		{"loong64", loong64OperandTests},154		{"s390x", s390xOperandTests},155	} {156		t.Run(sub.arch, func(t *testing.T) {157			parser := newParser(sub.arch)158			for _, test := range sub.tests {159				parser.start(lex.Tokenize(test.input))160				name, _, ok := parser.funcAddress()161162				isFuncSym := strings.HasSuffix(test.input, "(SB)") &&163					// Ignore static symbols.164					!strings.Contains(test.input, "<>")165166				wantName := ""167				if isFuncSym {168					// Strip $|* and (SB) and +Int.169					wantName = test.output[:len(test.output)-4]170					if strings.HasPrefix(wantName, "$") || strings.HasPrefix(wantName, "*") {171						wantName = wantName[1:]172					}173					if i := strings.Index(wantName, "+"); i >= 0 {174						wantName = wantName[:i]175					}176				}177				if ok != isFuncSym || name != wantName {178					t.Errorf("fail at %s as function address: got %s, %v; expected %s, %v", test.input, name, ok, wantName, isFuncSym)179				}180			}181		})182	}183}184185type operandTest struct {186	input, output string187}188189type badOperandTest struct {190	input, error string191}192193// Examples collected by scanning all the assembly in the standard repo.194195var amd64OperandTests = []operandTest{196	{"$(-1.0)", "$(-1.0)"},197	{"$(0.0)", "$(0.0)"},198	{"$(0x2000000+116)", "$33554548"},199	{"$(0x3F<<7)", "$8064"},200	{"$(112+8)", "$120"},201	{"$(1<<63)", "$-9223372036854775808"},202	{"$-1", "$-1"},203	{"$0", "$0"},204	{"$0-0", "$0"},205	{"$0-16", "$-16"},206	{"$0x000FFFFFFFFFFFFF", "$4503599627370495"},207	{"$0x01", "$1"},208	{"$0x02", "$2"},209	{"$0x04", "$4"},210	{"$0x3FE", "$1022"},211	{"$0x7fffffe00000", "$140737486258176"},212	{"$0xfffffffffffff001", "$-4095"},213	{"$1", "$1"},214	{"$1.0", "$(1.0)"},215	{"$10", "$10"},216	{"$1000", "$1000"},217	{"$1000000", "$1000000"},218	{"$1000000000", "$1000000000"},219	{"$__tsan_func_enter(SB)", "$__tsan_func_enter(SB)"},220	{"$main(SB)", "$main(SB)"},221	{"$masks<>(SB)", "$masks<>(SB)"},222	{"$setg_gcc<>(SB)", "$setg_gcc<>(SB)"},223	{"$shifts<>(SB)", "$shifts<>(SB)"},224	{"$~(1<<63)", "$9223372036854775807"},225	{"$~0x3F", "$-64"},226	{"$~15", "$-16"},227	{"(((8)&0xf)*4)(SP)", "32(SP)"},228	{"(((8-14)&0xf)*4)(SP)", "40(SP)"},229	{"(6+8)(AX)", "14(AX)"},230	{"(8*4)(BP)", "32(BP)"},231	{"(AX)", "(AX)"},232	{"(AX)(CX*8)", "(AX)(CX*8)"},233	{"(BP)(CX*4)", "(BP)(CX*4)"},234	{"(BP)(DX*4)", "(BP)(DX*4)"},235	{"(BP)(R8*4)", "(BP)(R8*4)"},236	{"(BX)", "(BX)"},237	{"(DI)", "(DI)"},238	{"(DI)(BX*1)", "(DI)(BX*1)"},239	{"(DX)", "(DX)"},240	{"(R9)", "(R9)"},241	{"(R9)(BX*8)", "(R9)(BX*8)"},242	{"(SI)", "(SI)"},243	{"(SI)(BX*1)", "(SI)(BX*1)"},244	{"(SI)(DX*1)", "(SI)(DX*1)"},245	{"(SP)", "(SP)"},246	{"(SP)(AX*4)", "(SP)(AX*4)"},247	{"32(SP)(BX*2)", "32(SP)(BX*2)"},248	{"32323(SP)(R8*4)", "32323(SP)(R8*4)"},249	{"+3(PC)", "3(PC)"},250	{"-1(DI)(BX*1)", "-1(DI)(BX*1)"},251	{"-3(PC)", "-3(PC)"},252	{"-64(SI)(BX*1)", "-64(SI)(BX*1)"},253	{"-96(SI)(BX*1)", "-96(SI)(BX*1)"},254	{"AL", "AL"},255	{"AX", "AX"},256	{"BP", "BP"},257	{"BX", "BX"},258	{"CX", "CX"},259	{"DI", "DI"},260	{"DX", "DX"},261	{"R10", "R10"},262	{"R10", "R10"},263	{"R11", "R11"},264	{"R12", "R12"},265	{"R13", "R13"},266	{"R14", "R14"},267	{"R15", "R15"},268	{"R8", "R8"},269	{"R9", "R9"},270	{"g", "R14"},271	{"SI", "SI"},272	{"SP", "SP"},273	{"X0", "X0"},274	{"X1", "X1"},275	{"X10", "X10"},276	{"X11", "X11"},277	{"X12", "X12"},278	{"X13", "X13"},279	{"X14", "X14"},280	{"X15", "X15"},281	{"X2", "X2"},282	{"X3", "X3"},283	{"X4", "X4"},284	{"X5", "X5"},285	{"X6", "X6"},286	{"X7", "X7"},287	{"X8", "X8"},288	{"X9", "X9"},289	{"_expand_key_128<>(SB)", "_expand_key_128<>(SB)"},290	{"_seek<>(SB)", "_seek<>(SB)"},291	{"a2+16(FP)", "a2+16(FP)"},292	{"addr2+24(FP)", "addr2+24(FP)"},293	{"asmcgocall<>(SB)", "asmcgocall<>(SB)"},294	{"b+24(FP)", "b+24(FP)"},295	{"b_len+32(FP)", "b_len+32(FP)"},296	{"racecall<>(SB)", "racecall<>(SB)"},297	{"rcv_name+20(FP)", "rcv_name+20(FP)"},298	{"retoffset+28(FP)", "retoffset+28(FP)"},299	{"runtime·_GetStdHandle(SB)", "runtime._GetStdHandle(SB)"},300	{"sync\u2215atomic·AddInt64(SB)", "sync/atomic.AddInt64(SB)"},301	{"timeout+20(FP)", "timeout+20(FP)"},302	{"ts+16(FP)", "ts+16(FP)"},303	{"x+24(FP)", "x+24(FP)"},304	{"x·y(SB)", "x.y(SB)"},305	{"x·y(SP)", "x.y(SP)"},306	{"x·y+8(SB)", "x.y+8(SB)"},307	{"x·y+8(SP)", "x.y+8(SP)"},308	{"y+56(FP)", "y+56(FP)"},309	{"·AddUint32(SB)", "pkg.AddUint32(SB)"},310	{"·callReflect(SB)", "pkg.callReflect(SB)"},311	{"[X0-X0]", "[X0-X0]"},312	{"[ Z9 - Z12 ]", "[Z9-Z12]"},313	{"[X0-AX]", "[X0-AX]"},314	{"[AX-X0]", "[AX-X0]"},315	{"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.316}317318var amd64RuntimeOperandTests = []operandTest{319	{"$bar<ABI0>(SB)", "$bar<ABI0>(SB)"},320	{"$foo<ABIInternal>(SB)", "$foo<ABIInternal>(SB)"},321}322323var amd64BadOperandTests = []badOperandTest{324	{"[", "register list: expected ']', found EOF"},325	{"[4", "register list: bad low register in `[4`"},326	{"[]", "register list: bad low register in `[]`"},327	{"[f-x]", "register list: bad low register in `[f`"},328	{"[r10-r13]", "register list: bad low register in `[r10`"},329	{"[k3-k6]", "register list: bad low register in `[k3`"},330	{"[X0]", "register list: expected '-' after `[X0`, found ']'"},331	{"[X0-]", "register list: bad high register in `[X0-]`"},332	{"[X0-x]", "register list: bad high register in `[X0-x`"},333	{"[X0-X1-X2]", "register list: expected ']' after `[X0-X1`, found '-'"},334	{"[X0,X3]", "register list: expected '-' after `[X0`, found ','"},335	{"[X0,X1,X2,X3]", "register list: expected '-' after `[X0`, found ','"},336	{"$foo<ABI0>", "ABI selector only permitted when compiling runtime, reference was to \"foo\""},337}338339var amd64BadOperandRuntimeTests = []badOperandTest{340	{"$foo<bletch>", "malformed ABI selector \"bletch\" in reference to \"foo\""},341}342343var x86OperandTests = []operandTest{344	{"$(2.928932188134524e-01)", "$(0.29289321881345243)"},345	{"$-1", "$-1"},346	{"$0", "$0"},347	{"$0x00000000", "$0"},348	{"$runtime·badmcall(SB)", "$runtime.badmcall(SB)"},349	{"$setg_gcc<>(SB)", "$setg_gcc<>(SB)"},350	{"$~15", "$-16"},351	{"(-64*1024+104)(SP)", "-65432(SP)"},352	{"(0*4)(BP)", "(BP)"},353	{"(1*4)(DI)", "4(DI)"},354	{"(4*4)(BP)", "16(BP)"},355	{"(AX)", "(AX)"},356	{"(BP)(CX*4)", "(BP)(CX*4)"},357	{"(BP*8)", "0(BP*8)"},358	{"(BX)", "(BX)"},359	{"(SP)", "(SP)"},360	{"*AX", "AX"}, // TODO: Should make * illegal here; a simple alias for JMP AX.361	{"*runtime·_GetStdHandle(SB)", "*runtime._GetStdHandle(SB)"},362	{"-(4+12)(DI)", "-16(DI)"},363	{"-1(DI)(BX*1)", "-1(DI)(BX*1)"},364	{"-96(DI)(BX*1)", "-96(DI)(BX*1)"},365	{"0(AX)", "(AX)"},366	{"0(BP)", "(BP)"},367	{"0(BX)", "(BX)"},368	{"4(AX)", "4(AX)"},369	{"AL", "AL"},370	{"AX", "AX"},371	{"BP", "BP"},372	{"BX", "BX"},373	{"CX", "CX"},374	{"DI", "DI"},375	{"DX", "DX"},376	{"F0", "F0"},377	{"GS", "GS"},378	{"SI", "SI"},379	{"SP", "SP"},380	{"X0", "X0"},381	{"X1", "X1"},382	{"X2", "X2"},383	{"X3", "X3"},384	{"X4", "X4"},385	{"X5", "X5"},386	{"X6", "X6"},387	{"X7", "X7"},388	{"asmcgocall<>(SB)", "asmcgocall<>(SB)"},389	{"ax+4(FP)", "ax+4(FP)"},390	{"ptime-12(SP)", "ptime-12(SP)"},391	{"runtime·_NtWaitForSingleObject(SB)", "runtime._NtWaitForSingleObject(SB)"},392	{"s(FP)", "s(FP)"},393	{"sec+4(FP)", "sec+4(FP)"},394	{"shifts<>(SB)(CX*8)", "shifts<>(SB)(CX*8)"},395	{"x+4(FP)", "x+4(FP)"},396	{"·AddUint32(SB)", "pkg.AddUint32(SB)"},397	{"·reflectcall(SB)", "pkg.reflectcall(SB)"},398	{"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.399}400401var armOperandTests = []operandTest{402	{"$0", "$0"},403	{"$256", "$256"},404	{"(R0)", "(R0)"},405	{"(R11)", "(R11)"},406	{"(g)", "(g)"},407	{"-12(R4)", "-12(R4)"},408	{"0(PC)", "0(PC)"},409	{"1024", "1024"},410	{"12(R(1))", "12(R1)"},411	{"12(R13)", "12(R13)"},412	{"R0", "R0"},413	{"R0->(32-1)", "R0->31"},414	{"R0<<R1", "R0<<R1"},415	{"R0>>R(1)", "R0>>R1"},416	{"R0@>(32-1)", "R0@>31"},417	{"R1", "R1"},418	{"R11", "R11"},419	{"R12", "R12"},420	{"R13", "R13"},421	{"R14", "R14"},422	{"R15", "R15"},423	{"R1<<2(R3)", "R1<<2(R3)"},424	{"R(1)<<2(R(3))", "R1<<2(R3)"},425	{"R2", "R2"},426	{"R3", "R3"},427	{"R4", "R4"},428	{"R(4)", "R4"},429	{"R5", "R5"},430	{"R6", "R6"},431	{"R7", "R7"},432	{"R8", "R8"},433	{"[R0,R1,g,R15]", "[R0,R1,g,R15]"},434	{"[R0-R7]", "[R0,R1,R2,R3,R4,R5,R6,R7]"},435	{"[R(0)-R(7)]", "[R0,R1,R2,R3,R4,R5,R6,R7]"},436	{"[R0]", "[R0]"},437	{"[R1-R12]", "[R1,R2,R3,R4,R5,R6,R7,R8,R9,g,R11,R12]"},438	{"armCAS64(SB)", "armCAS64(SB)"},439	{"asmcgocall<>(SB)", "asmcgocall<>(SB)"},440	{"c+28(FP)", "c+28(FP)"},441	{"g", "g"},442	{"gosave<>(SB)", "gosave<>(SB)"},443	{"retlo+12(FP)", "retlo+12(FP)"},444	{"runtime·gogo(SB)", "runtime.gogo(SB)"},445	{"·AddUint32(SB)", "pkg.AddUint32(SB)"},446	{"(R1, R3)", "(R1, R3)"},447	{"[R0,R1,g,R15", ""}, // Issue 11764 - asm hung parsing ']' missing register lists.448	{"[):[o-FP", ""},     // Issue 12469 - there was no infinite loop for ARM; these are just sanity checks.449	{"[):[R0-FP", ""},450	{"(", ""}, // Issue 12466 - backed up before beginning of line.451}452453var ppc64OperandTests = []operandTest{454	{"$((1<<63)-1)", "$9223372036854775807"},455	{"$(-64*1024)", "$-65536"},456	{"$(1024 * 8)", "$8192"},457	{"$-1", "$-1"},458	{"$-24(R4)", "$-24(R4)"},459	{"$0", "$0"},460	{"$0(R1)", "$(R1)"},461	{"$0.5", "$(0.5)"},462	{"$0x7000", "$28672"},463	{"$0x88888eef", "$2290650863"},464	{"$1", "$1"},465	{"$_main<>(SB)", "$_main<>(SB)"},466	{"$argframe(FP)", "$argframe(FP)"},467	{"$runtime·tlsg(SB)", "$runtime.tlsg(SB)"},468	{"$~3", "$-4"},469	{"(-288-3*8)(R1)", "-312(R1)"},470	{"(16)(R7)", "16(R7)"},471	{"(8)(g)", "8(g)"},472	{"(CTR)", "(CTR)"},473	{"(R0)", "(R0)"},474	{"(R3)", "(R3)"},475	{"(R4)", "(R4)"},476	{"(R5)", "(R5)"},477	{"(R5)(R6*1)", "(R5)(R6*1)"},478	{"(R5+R6)", "(R5)(R6)"},479	{"-1(R4)", "-1(R4)"},480	{"-1(R5)", "-1(R5)"},481	{"6(PC)", "6(PC)"},482	{"CR7", "CR7"},483	{"CTR", "CTR"},484	{"VS0", "VS0"},485	{"VS1", "VS1"},486	{"VS2", "VS2"},487	{"VS3", "VS3"},488	{"VS4", "VS4"},489	{"VS5", "VS5"},490	{"VS6", "VS6"},491	{"VS7", "VS7"},492	{"VS8", "VS8"},493	{"VS9", "VS9"},494	{"VS10", "VS10"},495	{"VS11", "VS11"},496	{"VS12", "VS12"},497	{"VS13", "VS13"},498	{"VS14", "VS14"},499	{"VS15", "VS15"},500	{"VS16", "VS16"},501	{"VS17", "VS17"},502	{"VS18", "VS18"},503	{"VS19", "VS19"},504	{"VS20", "VS20"},505	{"VS21", "VS21"},506	{"VS22", "VS22"},507	{"VS23", "VS23"},508	{"VS24", "VS24"},509	{"VS25", "VS25"},510	{"VS26", "VS26"},511	{"VS27", "VS27"},512	{"VS28", "VS28"},513	{"VS29", "VS29"},514	{"VS30", "VS30"},515	{"VS31", "VS31"},516	{"VS32", "VS32"},517	{"VS33", "VS33"},518	{"VS34", "VS34"},519	{"VS35", "VS35"},520	{"VS36", "VS36"},521	{"VS37", "VS37"},522	{"VS38", "VS38"},523	{"VS39", "VS39"},524	{"VS40", "VS40"},525	{"VS41", "VS41"},526	{"VS42", "VS42"},527	{"VS43", "VS43"},528	{"VS44", "VS44"},529	{"VS45", "VS45"},530	{"VS46", "VS46"},531	{"VS47", "VS47"},532	{"VS48", "VS48"},533	{"VS49", "VS49"},534	{"VS50", "VS50"},535	{"VS51", "VS51"},536	{"VS52", "VS52"},537	{"VS53", "VS53"},538	{"VS54", "VS54"},539	{"VS55", "VS55"},540	{"VS56", "VS56"},541	{"VS57", "VS57"},542	{"VS58", "VS58"},543	{"VS59", "VS59"},544	{"VS60", "VS60"},545	{"VS61", "VS61"},546	{"VS62", "VS62"},547	{"VS63", "VS63"},548	{"V0", "V0"},549	{"V1", "V1"},550	{"V2", "V2"},551	{"V3", "V3"},552	{"V4", "V4"},553	{"V5", "V5"},554	{"V6", "V6"},555	{"V7", "V7"},556	{"V8", "V8"},557	{"V9", "V9"},558	{"V10", "V10"},559	{"V11", "V11"},560	{"V12", "V12"},561	{"V13", "V13"},562	{"V14", "V14"},563	{"V15", "V15"},564	{"V16", "V16"},565	{"V17", "V17"},566	{"V18", "V18"},567	{"V19", "V19"},568	{"V20", "V20"},569	{"V21", "V21"},570	{"V22", "V22"},571	{"V23", "V23"},572	{"V24", "V24"},573	{"V25", "V25"},574	{"V26", "V26"},575	{"V27", "V27"},576	{"V28", "V28"},577	{"V29", "V29"},578	{"V30", "V30"},579	{"V31", "V31"},580	{"F14", "F14"},581	{"F15", "F15"},582	{"F16", "F16"},583	{"F17", "F17"},584	{"F18", "F18"},585	{"F19", "F19"},586	{"F20", "F20"},587	{"F21", "F21"},588	{"F22", "F22"},589	{"F23", "F23"},590	{"F24", "F24"},591	{"F25", "F25"},592	{"F26", "F26"},593	{"F27", "F27"},594	{"F28", "F28"},595	{"F29", "F29"},596	{"F30", "F30"},597	{"F31", "F31"},598	{"LR", "LR"},599	{"R0", "R0"},600	{"R1", "R1"},601	{"R11", "R11"},602	{"R12", "R12"},603	{"R13", "R13"},604	{"R14", "R14"},605	{"R15", "R15"},606	{"R16", "R16"},607	{"R17", "R17"},608	{"R18", "R18"},609	{"R19", "R19"},610	{"R2", "R2"},611	{"R20", "R20"},612	{"R21", "R21"},613	{"R22", "R22"},614	{"R23", "R23"},615	{"R24", "R24"},616	{"R25", "R25"},617	{"R26", "R26"},618	{"R27", "R27"},619	{"R28", "R28"},620	{"R29", "R29"},621	{"R3", "R3"},622	{"R31", "R31"},623	{"R4", "R4"},624	{"R5", "R5"},625	{"R6", "R6"},626	{"R7", "R7"},627	{"R8", "R8"},628	{"R9", "R9"},629	{"SPR(269)", "SPR(269)"},630	{"a(FP)", "a(FP)"},631	{"g", "g"},632	{"ret+8(FP)", "ret+8(FP)"},633	{"runtime·abort(SB)", "runtime.abort(SB)"},634	{"·AddUint32(SB)", "pkg.AddUint32(SB)"},635	{"·trunc(SB)", "pkg.trunc(SB)"},636	{"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.637}638639var arm64OperandTests = []operandTest{640	{"$0", "$0"},641	{"$0.5", "$(0.5)"},642	{"0(R26)", "(R26)"},643	{"0(RSP)", "(RSP)"},644	{"$1", "$1"},645	{"$-1", "$-1"},646	{"$1000", "$1000"},647	{"$1000000000", "$1000000000"},648	{"$0x7fff3c000", "$34358935552"},649	{"$1234", "$1234"},650	{"$~15", "$-16"},651	{"$16", "$16"},652	{"-16(RSP)", "-16(RSP)"},653	{"16(RSP)", "16(RSP)"},654	{"1(R1)", "1(R1)"},655	{"-1(R4)", "-1(R4)"},656	{"18740(R5)", "18740(R5)"},657	{"$2", "$2"},658	{"$-24(R4)", "$-24(R4)"},659	{"-24(RSP)", "-24(RSP)"},660	{"$24(RSP)", "$24(RSP)"},661	{"-32(RSP)", "-32(RSP)"},662	{"$48", "$48"},663	{"$(-64*1024)(R7)", "$-65536(R7)"},664	{"$(8-1)", "$7"},665	{"a+0(FP)", "a(FP)"},666	{"a1+8(FP)", "a1+8(FP)"},667	{"·AddInt32(SB)", `pkg.AddInt32(SB)`},668	{"runtime·divWVW(SB)", "runtime.divWVW(SB)"},669	{"$argframe+0(FP)", "$argframe(FP)"},670	{"$asmcgocall<>(SB)", "$asmcgocall<>(SB)"},671	{"EQ", "EQ"},672	{"F29", "F29"},673	{"F3", "F3"},674	{"F30", "F30"},675	{"g", "g"},676	{"LR", "R30"},677	{"(LR)", "(R30)"},678	{"R0", "R0"},679	{"R10", "R10"},680	{"R11", "R11"},681	{"R18_PLATFORM", "R18"},682	{"$4503601774854144.0", "$(4503601774854144.0)"},683	{"$runtime·badsystemstack(SB)", "$runtime.badsystemstack(SB)"},684	{"ZR", "ZR"},685	{"(ZR)", "(ZR)"},686	{"(R29, RSP)", "(R29, RSP)"},687	{"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.688}689690var mips64OperandTests = []operandTest{691	{"$((1<<63)-1)", "$9223372036854775807"},692	{"$(-64*1024)", "$-65536"},693	{"$(1024 * 8)", "$8192"},694	{"$-1", "$-1"},695	{"$-24(R4)", "$-24(R4)"},696	{"$0", "$0"},697	{"$0(R1)", "$(R1)"},698	{"$0.5", "$(0.5)"},699	{"$0x7000", "$28672"},700	{"$0x88888eef", "$2290650863"},701	{"$1", "$1"},702	{"$_main<>(SB)", "$_main<>(SB)"},703	{"$argframe(FP)", "$argframe(FP)"},704	{"$~3", "$-4"},705	{"(-288-3*8)(R1)", "-312(R1)"},706	{"(16)(R7)", "16(R7)"},707	{"(8)(g)", "8(g)"},708	{"(R0)", "(R0)"},709	{"(R3)", "(R3)"},710	{"(R4)", "(R4)"},711	{"(R5)", "(R5)"},712	{"-1(R4)", "-1(R4)"},713	{"-1(R5)", "-1(R5)"},714	{"6(PC)", "6(PC)"},715	{"F14", "F14"},716	{"F15", "F15"},717	{"F16", "F16"},718	{"F17", "F17"},719	{"F18", "F18"},720	{"F19", "F19"},721	{"F20", "F20"},722	{"F21", "F21"},723	{"F22", "F22"},724	{"F23", "F23"},725	{"F24", "F24"},726	{"F25", "F25"},727	{"F26", "F26"},728	{"F27", "F27"},729	{"F28", "F28"},730	{"F29", "F29"},731	{"F30", "F30"},732	{"F31", "F31"},733	{"R0", "R0"},734	{"R1", "R1"},735	{"R11", "R11"},736	{"R12", "R12"},737	{"R13", "R13"},738	{"R14", "R14"},739	{"R15", "R15"},740	{"R16", "R16"},741	{"R17", "R17"},742	{"R18", "R18"},743	{"R19", "R19"},744	{"R2", "R2"},745	{"R20", "R20"},746	{"R21", "R21"},747	{"R22", "R22"},748	{"R23", "R23"},749	{"R24", "R24"},750	{"R25", "R25"},751	{"R26", "R26"},752	{"R27", "R27"},753	{"R29", "R29"},754	{"R3", "R3"},755	{"R31", "R31"},756	{"R4", "R4"},757	{"R5", "R5"},758	{"R6", "R6"},759	{"R7", "R7"},760	{"R8", "R8"},761	{"R9", "R9"},762	{"LO", "LO"},763	{"a(FP)", "a(FP)"},764	{"g", "g"},765	{"RSB", "R28"},766	{"ret+8(FP)", "ret+8(FP)"},767	{"runtime·abort(SB)", "runtime.abort(SB)"},768	{"·AddUint32(SB)", "pkg.AddUint32(SB)"},769	{"·trunc(SB)", "pkg.trunc(SB)"},770	{"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.771}772773var mipsOperandTests = []operandTest{774	{"$((1<<63)-1)", "$9223372036854775807"},775	{"$(-64*1024)", "$-65536"},776	{"$(1024 * 8)", "$8192"},777	{"$-1", "$-1"},778	{"$-24(R4)", "$-24(R4)"},779	{"$0", "$0"},780	{"$0(R1)", "$(R1)"},781	{"$0.5", "$(0.5)"},782	{"$0x7000", "$28672"},783	{"$0x88888eef", "$2290650863"},784	{"$1", "$1"},785	{"$_main<>(SB)", "$_main<>(SB)"},786	{"$argframe(FP)", "$argframe(FP)"},787	{"$~3", "$-4"},788	{"(-288-3*8)(R1)", "-312(R1)"},789	{"(16)(R7)", "16(R7)"},790	{"(8)(g)", "8(g)"},791	{"(R0)", "(R0)"},792	{"(R3)", "(R3)"},793	{"(R4)", "(R4)"},794	{"(R5)", "(R5)"},795	{"-1(R4)", "-1(R4)"},796	{"-1(R5)", "-1(R5)"},797	{"6(PC)", "6(PC)"},798	{"F14", "F14"},799	{"F15", "F15"},800	{"F16", "F16"},801	{"F17", "F17"},802	{"F18", "F18"},803	{"F19", "F19"},804	{"F20", "F20"},805	{"F21", "F21"},806	{"F22", "F22"},807	{"F23", "F23"},808	{"F24", "F24"},809	{"F25", "F25"},810	{"F26", "F26"},811	{"F27", "F27"},812	{"F28", "F28"},813	{"F29", "F29"},814	{"F30", "F30"},815	{"F31", "F31"},816	{"R0", "R0"},817	{"R1", "R1"},818	{"R11", "R11"},819	{"R12", "R12"},820	{"R13", "R13"},821	{"R14", "R14"},822	{"R15", "R15"},823	{"R16", "R16"},824	{"R17", "R17"},825	{"R18", "R18"},826	{"R19", "R19"},827	{"R2", "R2"},828	{"R20", "R20"},829	{"R21", "R21"},830	{"R22", "R22"},831	{"R23", "R23"},832	{"R24", "R24"},833	{"R25", "R25"},834	{"R26", "R26"},835	{"R27", "R27"},836	{"R28", "R28"},837	{"R29", "R29"},838	{"R3", "R3"},839	{"R31", "R31"},840	{"R4", "R4"},841	{"R5", "R5"},842	{"R6", "R6"},843	{"R7", "R7"},844	{"R8", "R8"},845	{"R9", "R9"},846	{"LO", "LO"},847	{"a(FP)", "a(FP)"},848	{"g", "g"},849	{"ret+8(FP)", "ret+8(FP)"},850	{"runtime·abort(SB)", "runtime.abort(SB)"},851	{"·AddUint32(SB)", "pkg.AddUint32(SB)"},852	{"·trunc(SB)", "pkg.trunc(SB)"},853	{"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.854}855856var loong64OperandTests = []operandTest{857	{"$((1<<63)-1)", "$9223372036854775807"},858	{"$(-64*1024)", "$-65536"},859	{"$(1024 * 8)", "$8192"},860	{"$-1", "$-1"},861	{"$-24(R4)", "$-24(R4)"},862	{"$0", "$0"},863	{"$0(R1)", "$(R1)"},864	{"$0.5", "$(0.5)"},865	{"$0x7000", "$28672"},866	{"$0x88888eef", "$2290650863"},867	{"$1", "$1"},868	{"$_main<>(SB)", "$_main<>(SB)"},869	{"$argframe(FP)", "$argframe(FP)"},870	{"$~3", "$-4"},871	{"(-288-3*8)(R1)", "-312(R1)"},872	{"(16)(R7)", "16(R7)"},873	{"(8)(g)", "8(g)"},874	{"(R0)", "(R0)"},875	{"(R3)", "(R3)"},876	{"(R4)", "(R4)"},877	{"(R5)", "(R5)"},878	{"-1(R4)", "-1(R4)"},879	{"-1(R5)", "-1(R5)"},880	{"6(PC)", "6(PC)"},881	{"F14", "F14"},882	{"F15", "F15"},883	{"F16", "F16"},884	{"F17", "F17"},885	{"F18", "F18"},886	{"F19", "F19"},887	{"F20", "F20"},888	{"F21", "F21"},889	{"F22", "F22"},890	{"F23", "F23"},891	{"F24", "F24"},892	{"F25", "F25"},893	{"F26", "F26"},894	{"F27", "F27"},895	{"F28", "F28"},896	{"F29", "F29"},897	{"F30", "F30"},898	{"F31", "F31"},899	{"R0", "R0"},900	{"R1", "R1"},901	{"R11", "R11"},902	{"R12", "R12"},903	{"R13", "R13"},904	{"R14", "R14"},905	{"R15", "R15"},906	{"R16", "R16"},907	{"R17", "R17"},908	{"R18", "R18"},909	{"R19", "R19"},910	{"R2", "R2"},911	{"R20", "R20"},912	{"R21", "R21"},913	{"R23", "R23"},914	{"R24", "R24"},915	{"R25", "R25"},916	{"R26", "R26"},917	{"R27", "R27"},918	{"R28", "R28"},919	{"R29", "R29"},920	{"R3", "R3"},921	{"R30", "R30"},922	{"R31", "R31"},923	{"R4", "R4"},924	{"R5", "R5"},925	{"R6", "R6"},926	{"R7", "R7"},927	{"R8", "R8"},928	{"R9", "R9"},929	{"a(FP)", "a(FP)"},930	{"g", "g"},931	{"ret+8(FP)", "ret+8(FP)"},932	{"runtime·abort(SB)", "runtime.abort(SB)"},933	{"·AddUint32(SB)", "pkg.AddUint32(SB)"},934	{"·trunc(SB)", "pkg.trunc(SB)"},935	{"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.936}937938var s390xOperandTests = []operandTest{939	{"$((1<<63)-1)", "$9223372036854775807"},940	{"$(-64*1024)", "$-65536"},941	{"$(1024 * 8)", "$8192"},942	{"$-1", "$-1"},943	{"$-24(R4)", "$-24(R4)"},944	{"$0", "$0"},945	{"$0(R1)", "$(R1)"},946	{"$0.5", "$(0.5)"},947	{"$0x7000", "$28672"},948	{"$0x88888eef", "$2290650863"},949	{"$1", "$1"},950	{"$_main<>(SB)", "$_main<>(SB)"},951	{"$argframe(FP)", "$argframe(FP)"},952	{"$~3", "$-4"},953	{"(-288-3*8)(R1)", "-312(R1)"},954	{"(16)(R7)", "16(R7)"},955	{"(8)(g)", "8(g)"},956	{"(R0)", "(R0)"},957	{"(R3)", "(R3)"},958	{"(R4)", "(R4)"},959	{"(R5)", "(R5)"},960	{"-1(R4)", "-1(R4)"},961	{"-1(R5)", "-1(R5)"},962	{"6(PC)", "6(PC)"},963	{"R0", "R0"},964	{"R1", "R1"},965	{"R2", "R2"},966	{"R3", "R3"},967	{"R4", "R4"},968	{"R5", "R5"},969	{"R6", "R6"},970	{"R7", "R7"},971	{"R8", "R8"},972	{"R9", "R9"},973	{"R10", "R10"},974	{"R11", "R11"},975	{"R12", "R12"},976	// {"R13", "R13"}, R13 is g977	{"R14", "R14"},978	{"R15", "R15"},979	{"F0", "F0"},980	{"F1", "F1"},981	{"F2", "F2"},982	{"F3", "F3"},983	{"F4", "F4"},984	{"F5", "F5"},985	{"F6", "F6"},986	{"F7", "F7"},987	{"F8", "F8"},988	{"F9", "F9"},989	{"F10", "F10"},990	{"F11", "F11"},991	{"F12", "F12"},992	{"F13", "F13"},993	{"F14", "F14"},994	{"F15", "F15"},995	{"V0", "V0"},996	{"V1", "V1"},997	{"V2", "V2"},998	{"V3", "V3"},999	{"V4", "V4"},1000	{"V5", "V5"},1001	{"V6", "V6"},1002	{"V7", "V7"},1003	{"V8", "V8"},1004	{"V9", "V9"},1005	{"V10", "V10"},1006	{"V11", "V11"},1007	{"V12", "V12"},1008	{"V13", "V13"},1009	{"V14", "V14"},1010	{"V15", "V15"},1011	{"V16", "V16"},1012	{"V17", "V17"},1013	{"V18", "V18"},1014	{"V19", "V19"},1015	{"V20", "V20"},1016	{"V21", "V21"},1017	{"V22", "V22"},1018	{"V23", "V23"},1019	{"V24", "V24"},1020	{"V25", "V25"},1021	{"V26", "V26"},1022	{"V27", "V27"},1023	{"V28", "V28"},1024	{"V29", "V29"},1025	{"V30", "V30"},1026	{"V31", "V31"},1027	{"a(FP)", "a(FP)"},1028	{"g", "g"},1029	{"ret+8(FP)", "ret+8(FP)"},1030	{"runtime·abort(SB)", "runtime.abort(SB)"},1031	{"·AddUint32(SB)", "pkg.AddUint32(SB)"},1032	{"·trunc(SB)", "pkg.trunc(SB)"},1033	{"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.1034}

Code quality findings 1

May hide panics instead of handling errors properly; use only with specific panic recovery logic
warning correctness recover-without-defer
e := recover()

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.