diff options
Diffstat (limited to 'src/cmd/asm/internal/asm')
-rw-r--r-- | src/cmd/asm/internal/asm/asm.go | 4 | ||||
-rw-r--r-- | src/cmd/asm/internal/asm/endtoend_test.go | 32 | ||||
-rw-r--r-- | src/cmd/asm/internal/asm/expr_test.go | 4 | ||||
-rw-r--r-- | src/cmd/asm/internal/asm/line_test.go | 2 | ||||
-rw-r--r-- | src/cmd/asm/internal/asm/operand_test.go | 42 | ||||
-rw-r--r-- | src/cmd/asm/internal/asm/parse.go | 83 | ||||
-rw-r--r-- | src/cmd/asm/internal/asm/pseudo_test.go | 14 | ||||
-rw-r--r-- | src/cmd/asm/internal/asm/testdata/arm.s | 22 | ||||
-rw-r--r-- | src/cmd/asm/internal/asm/testdata/arm64.s | 119 | ||||
-rw-r--r-- | src/cmd/asm/internal/asm/testdata/arm64enc.s | 2 | ||||
-rw-r--r-- | src/cmd/asm/internal/asm/testdata/arm64error.s | 177 | ||||
-rw-r--r-- | src/cmd/asm/internal/asm/testdata/mips.s | 5 | ||||
-rw-r--r-- | src/cmd/asm/internal/asm/testdata/mips64.s | 9 | ||||
-rw-r--r-- | src/cmd/asm/internal/asm/testdata/ppc64.s | 55 | ||||
-rw-r--r-- | src/cmd/asm/internal/asm/testdata/riscv64.s | 17 | ||||
-rw-r--r-- | src/cmd/asm/internal/asm/testdata/riscv64error.s | 5 | ||||
-rw-r--r-- | src/cmd/asm/internal/asm/testdata/s390x.s | 8 |
17 files changed, 402 insertions, 198 deletions
diff --git a/src/cmd/asm/internal/asm/asm.go b/src/cmd/asm/internal/asm/asm.go index 563e794706..375ef803bb 100644 --- a/src/cmd/asm/internal/asm/asm.go +++ b/src/cmd/asm/internal/asm/asm.go @@ -445,7 +445,7 @@ func (p *Parser) asmJump(op obj.As, cond string, a []obj.Addr) { // BC x,CR0EQ,... // BC x,CR1LT,... // BC x,CR1GT,... - // The first and second case demonstrate a symbol name which is + // The first and second cases demonstrate a symbol name which is // effectively discarded. In these cases, the offset determines // the CR bit. prog.Reg = a[1].Reg @@ -909,7 +909,7 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) { p.append(prog, cond, true) } -// symbolName returns the symbol name, or an error string if none if available. +// symbolName returns the symbol name, or an error string if none is available. func symbolName(addr *obj.Addr) string { if addr.Sym != nil { return addr.Sym.Name diff --git a/src/cmd/asm/internal/asm/endtoend_test.go b/src/cmd/asm/internal/asm/endtoend_test.go index ef41667c8e..6e1aa1cd95 100644 --- a/src/cmd/asm/internal/asm/endtoend_test.go +++ b/src/cmd/asm/internal/asm/endtoend_test.go @@ -30,7 +30,7 @@ func testEndToEnd(t *testing.T, goarch, file string) { architecture, ctxt := setArch(goarch) architecture.Init(ctxt) lexer := lex.NewLexer(input) - parser := NewParser(ctxt, architecture, lexer, false) + parser := NewParser(ctxt, architecture, lexer) pList := new(obj.Plist) var ok bool testOut = new(strings.Builder) // The assembler writes test output to this buffer. @@ -68,6 +68,11 @@ Diff: continue } + // Ignore GLOBL. + if strings.HasPrefix(line, "GLOBL ") { + continue + } + // The general form of a test input line is: // // comment // INST args [// printed form] [// hex encoding] @@ -136,11 +141,17 @@ Diff: // Turn relative (PC) into absolute (PC) automatically, // so that most branch instructions don't need comments // giving the absolute form. - if len(f) > 0 && strings.HasSuffix(printed, "(PC)") { - last := f[len(f)-1] - n, err := strconv.Atoi(last[:len(last)-len("(PC)")]) + if len(f) > 0 && strings.Contains(printed, "(PC)") { + index := len(f) - 1 + suf := "(PC)" + for !strings.HasSuffix(f[index], suf) { + index-- + suf = "(PC)," + } + str := f[index] + n, err := strconv.Atoi(str[:len(str)-len(suf)]) if err == nil { - f[len(f)-1] = fmt.Sprintf("%d(PC)", seq+n) + f[index] = fmt.Sprintf("%d%s", seq+n, suf) } } @@ -186,7 +197,7 @@ Diff: t.Errorf(format, args...) ok = false } - obj.Flushplist(ctxt, pList, nil, "") + obj.Flushplist(ctxt, pList, nil) for p := top; p != nil; p = p.Link { if p.As == obj.ATEXT { @@ -272,8 +283,9 @@ var ( func testErrors(t *testing.T, goarch, file string, flags ...string) { input := filepath.Join("testdata", file+".s") architecture, ctxt := setArch(goarch) + architecture.Init(ctxt) lexer := lex.NewLexer(input) - parser := NewParser(ctxt, architecture, lexer, false) + parser := NewParser(ctxt, architecture, lexer) pList := new(obj.Plist) var ok bool ctxt.Bso = bufio.NewWriter(os.Stdout) @@ -299,7 +311,7 @@ func testErrors(t *testing.T, goarch, file string, flags ...string) { } } pList.Firstpc, ok = parser.Parse() - obj.Flushplist(ctxt, pList, nil, "") + obj.Flushplist(ctxt, pList, nil) if ok && !failed { t.Errorf("asm: %s had no errors", file) } @@ -366,10 +378,10 @@ func Test386EndToEnd(t *testing.T) { } func TestARMEndToEnd(t *testing.T) { - defer func(old int) { buildcfg.GOARM = old }(buildcfg.GOARM) + defer func(old int) { buildcfg.GOARM.Version = old }(buildcfg.GOARM.Version) for _, goarm := range []int{5, 6, 7} { t.Logf("GOARM=%d", goarm) - buildcfg.GOARM = goarm + buildcfg.GOARM.Version = goarm testEndToEnd(t, "arm", "arm") if goarm == 6 { testEndToEnd(t, "arm", "armv6") diff --git a/src/cmd/asm/internal/asm/expr_test.go b/src/cmd/asm/internal/asm/expr_test.go index e9c92df1f3..1251594349 100644 --- a/src/cmd/asm/internal/asm/expr_test.go +++ b/src/cmd/asm/internal/asm/expr_test.go @@ -57,7 +57,7 @@ var exprTests = []exprTest{ } func TestExpr(t *testing.T) { - p := NewParser(nil, nil, nil, false) // Expression evaluation uses none of these fields of the parser. + p := NewParser(nil, nil, nil) // Expression evaluation uses none of these fields of the parser. for i, test := range exprTests { p.start(lex.Tokenize(test.input)) result := int64(p.expr()) @@ -113,7 +113,7 @@ func TestBadExpr(t *testing.T) { } func runBadTest(i int, test badExprTest, t *testing.T) (err error) { - p := NewParser(nil, nil, nil, false) // Expression evaluation uses none of these fields of the parser. + p := NewParser(nil, nil, nil) // Expression evaluation uses none of these fields of the parser. p.start(lex.Tokenize(test.input)) return tryParse(t, func() { p.expr() diff --git a/src/cmd/asm/internal/asm/line_test.go b/src/cmd/asm/internal/asm/line_test.go index da857ced3a..01b058bd95 100644 --- a/src/cmd/asm/internal/asm/line_test.go +++ b/src/cmd/asm/internal/asm/line_test.go @@ -39,7 +39,7 @@ func testBadInstParser(t *testing.T, goarch string, tests []badInstTest) { for i, test := range tests { arch, ctxt := setArch(goarch) tokenizer := lex.NewTokenizer("", strings.NewReader(test.input+"\n"), nil) - parser := NewParser(ctxt, arch, tokenizer, false) + parser := NewParser(ctxt, arch, tokenizer) err := tryParse(t, func() { parser.Parse() diff --git a/src/cmd/asm/internal/asm/operand_test.go b/src/cmd/asm/internal/asm/operand_test.go index c7e251f50f..579f533223 100644 --- a/src/cmd/asm/internal/asm/operand_test.go +++ b/src/cmd/asm/internal/asm/operand_test.go @@ -23,12 +23,14 @@ func setArch(goarch string) (*arch.Arch, *obj.Link) { if architecture == nil { panic("asm: unrecognized architecture " + goarch) } - return architecture, obj.Linknew(architecture.LinkArch) + ctxt := obj.Linknew(architecture.LinkArch) + ctxt.Pkgpath = "pkg" + return architecture, ctxt } func newParser(goarch string) *Parser { architecture, ctxt := setArch(goarch) - return NewParser(ctxt, architecture, nil, false) + return NewParser(ctxt, architecture, nil) } // tryParse executes parse func in panicOnError=true context. @@ -76,7 +78,7 @@ func testOperandParser(t *testing.T, parser *Parser, tests []operandTest) { addr := obj.Addr{} parser.operand(&addr) var result string - if parser.compilingRuntime { + if parser.allowABI { result = obj.DconvWithABIDetail(&emptyProg, &addr) } else { result = obj.Dconv(&emptyProg, &addr) @@ -91,7 +93,7 @@ func TestAMD64OperandParser(t *testing.T) { parser := newParser("amd64") testOperandParser(t, parser, amd64OperandTests) testBadOperandParser(t, parser, amd64BadOperandTests) - parser.compilingRuntime = true + parser.allowABI = true testOperandParser(t, parser, amd64RuntimeOperandTests) testBadOperandParser(t, parser, amd64BadOperandRuntimeTests) } @@ -304,8 +306,8 @@ var amd64OperandTests = []operandTest{ {"x·y+8(SB)", "x.y+8(SB)"}, {"x·y+8(SP)", "x.y+8(SP)"}, {"y+56(FP)", "y+56(FP)"}, - {"·AddUint32(SB)", "\"\".AddUint32(SB)"}, - {"·callReflect(SB)", "\"\".callReflect(SB)"}, + {"·AddUint32(SB)", "pkg.AddUint32(SB)"}, + {"·callReflect(SB)", "pkg.callReflect(SB)"}, {"[X0-X0]", "[X0-X0]"}, {"[ Z9 - Z12 ]", "[Z9-Z12]"}, {"[X0-AX]", "[X0-AX]"}, @@ -391,8 +393,8 @@ var x86OperandTests = []operandTest{ {"sec+4(FP)", "sec+4(FP)"}, {"shifts<>(SB)(CX*8)", "shifts<>(SB)(CX*8)"}, {"x+4(FP)", "x+4(FP)"}, - {"·AddUint32(SB)", "\"\".AddUint32(SB)"}, - {"·reflectcall(SB)", "\"\".reflectcall(SB)"}, + {"·AddUint32(SB)", "pkg.AddUint32(SB)"}, + {"·reflectcall(SB)", "pkg.reflectcall(SB)"}, {"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms. } @@ -440,7 +442,7 @@ var armOperandTests = []operandTest{ {"gosave<>(SB)", "gosave<>(SB)"}, {"retlo+12(FP)", "retlo+12(FP)"}, {"runtime·gogo(SB)", "runtime.gogo(SB)"}, - {"·AddUint32(SB)", "\"\".AddUint32(SB)"}, + {"·AddUint32(SB)", "pkg.AddUint32(SB)"}, {"(R1, R3)", "(R1, R3)"}, {"[R0,R1,g,R15", ""}, // Issue 11764 - asm hung parsing ']' missing register lists. {"[):[o-FP", ""}, // Issue 12469 - there was no infinite loop for ARM; these are just sanity checks. @@ -629,8 +631,8 @@ var ppc64OperandTests = []operandTest{ {"g", "g"}, {"ret+8(FP)", "ret+8(FP)"}, {"runtime·abort(SB)", "runtime.abort(SB)"}, - {"·AddUint32(SB)", "\"\".AddUint32(SB)"}, - {"·trunc(SB)", "\"\".trunc(SB)"}, + {"·AddUint32(SB)", "pkg.AddUint32(SB)"}, + {"·trunc(SB)", "pkg.trunc(SB)"}, {"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms. } @@ -662,7 +664,7 @@ var arm64OperandTests = []operandTest{ {"$(8-1)", "$7"}, {"a+0(FP)", "a(FP)"}, {"a1+8(FP)", "a1+8(FP)"}, - {"·AddInt32(SB)", `"".AddInt32(SB)`}, + {"·AddInt32(SB)", `pkg.AddInt32(SB)`}, {"runtime·divWVW(SB)", "runtime.divWVW(SB)"}, {"$argframe+0(FP)", "$argframe(FP)"}, {"$asmcgocall<>(SB)", "$asmcgocall<>(SB)"}, @@ -763,8 +765,8 @@ var mips64OperandTests = []operandTest{ {"RSB", "R28"}, {"ret+8(FP)", "ret+8(FP)"}, {"runtime·abort(SB)", "runtime.abort(SB)"}, - {"·AddUint32(SB)", "\"\".AddUint32(SB)"}, - {"·trunc(SB)", "\"\".trunc(SB)"}, + {"·AddUint32(SB)", "pkg.AddUint32(SB)"}, + {"·trunc(SB)", "pkg.trunc(SB)"}, {"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms. } @@ -846,8 +848,8 @@ var mipsOperandTests = []operandTest{ {"g", "g"}, {"ret+8(FP)", "ret+8(FP)"}, {"runtime·abort(SB)", "runtime.abort(SB)"}, - {"·AddUint32(SB)", "\"\".AddUint32(SB)"}, - {"·trunc(SB)", "\"\".trunc(SB)"}, + {"·AddUint32(SB)", "pkg.AddUint32(SB)"}, + {"·trunc(SB)", "pkg.trunc(SB)"}, {"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms. } @@ -928,8 +930,8 @@ var loong64OperandTests = []operandTest{ {"g", "g"}, {"ret+8(FP)", "ret+8(FP)"}, {"runtime·abort(SB)", "runtime.abort(SB)"}, - {"·AddUint32(SB)", "\"\".AddUint32(SB)"}, - {"·trunc(SB)", "\"\".trunc(SB)"}, + {"·AddUint32(SB)", "pkg.AddUint32(SB)"}, + {"·trunc(SB)", "pkg.trunc(SB)"}, {"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms. } @@ -1026,7 +1028,7 @@ var s390xOperandTests = []operandTest{ {"g", "g"}, {"ret+8(FP)", "ret+8(FP)"}, {"runtime·abort(SB)", "runtime.abort(SB)"}, - {"·AddUint32(SB)", "\"\".AddUint32(SB)"}, - {"·trunc(SB)", "\"\".trunc(SB)"}, + {"·AddUint32(SB)", "pkg.AddUint32(SB)"}, + {"·trunc(SB)", "pkg.trunc(SB)"}, {"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms. } diff --git a/src/cmd/asm/internal/asm/parse.go b/src/cmd/asm/internal/asm/parse.go index 37f8e6c0bc..ef6c840dc2 100644 --- a/src/cmd/asm/internal/asm/parse.go +++ b/src/cmd/asm/internal/asm/parse.go @@ -12,6 +12,7 @@ import ( "log" "os" "strconv" + "strings" "text/scanner" "unicode/utf8" @@ -21,31 +22,33 @@ import ( "cmd/internal/obj" "cmd/internal/obj/arm64" "cmd/internal/obj/x86" + "cmd/internal/objabi" "cmd/internal/src" "cmd/internal/sys" ) type Parser struct { - lex lex.TokenReader - lineNum int // Line number in source file. - errorLine int // Line number of last error. - errorCount int // Number of errors. - sawCode bool // saw code in this file (as opposed to comments and blank lines) - pc int64 // virtual PC; count of Progs; doesn't advance for GLOBL or DATA. - input []lex.Token - inputPos int - pendingLabels []string // Labels to attach to next instruction. - labels map[string]*obj.Prog - toPatch []Patch - addr []obj.Addr - arch *arch.Arch - ctxt *obj.Link - firstProg *obj.Prog - lastProg *obj.Prog - dataAddr map[string]int64 // Most recent address for DATA for this symbol. - isJump bool // Instruction being assembled is a jump. - compilingRuntime bool - errorWriter io.Writer + lex lex.TokenReader + lineNum int // Line number in source file. + errorLine int // Line number of last error. + errorCount int // Number of errors. + sawCode bool // saw code in this file (as opposed to comments and blank lines) + pc int64 // virtual PC; count of Progs; doesn't advance for GLOBL or DATA. + input []lex.Token + inputPos int + pendingLabels []string // Labels to attach to next instruction. + labels map[string]*obj.Prog + toPatch []Patch + addr []obj.Addr + arch *arch.Arch + ctxt *obj.Link + firstProg *obj.Prog + lastProg *obj.Prog + dataAddr map[string]int64 // Most recent address for DATA for this symbol. + isJump bool // Instruction being assembled is a jump. + allowABI bool // Whether ABI selectors are allowed. + pkgPrefix string // Prefix to add to local symbols. + errorWriter io.Writer } type Patch struct { @@ -53,15 +56,20 @@ type Patch struct { label string } -func NewParser(ctxt *obj.Link, ar *arch.Arch, lexer lex.TokenReader, compilingRuntime bool) *Parser { +func NewParser(ctxt *obj.Link, ar *arch.Arch, lexer lex.TokenReader) *Parser { + pkgPrefix := obj.UnlinkablePkg + if ctxt != nil { + pkgPrefix = objabi.PathToPrefix(ctxt.Pkgpath) + } return &Parser{ - ctxt: ctxt, - arch: ar, - lex: lexer, - labels: make(map[string]*obj.Prog), - dataAddr: make(map[string]int64), - errorWriter: os.Stderr, - compilingRuntime: compilingRuntime, + ctxt: ctxt, + arch: ar, + lex: lexer, + labels: make(map[string]*obj.Prog), + dataAddr: make(map[string]int64), + errorWriter: os.Stderr, + allowABI: ctxt != nil && objabi.LookupPkgSpecial(ctxt.Pkgpath).AllowAsmABI, + pkgPrefix: pkgPrefix, } } @@ -401,7 +409,7 @@ func (p *Parser) operand(a *obj.Addr) { fallthrough default: // We have a symbol. Parse $sym±offset(symkind) - p.symbolReference(a, name, prefix) + p.symbolReference(a, p.qualifySymbol(name), prefix) } // fmt.Printf("SYM %s\n", obj.Dconv(&emptyProg, 0, a)) if p.peek() == scanner.EOF { @@ -769,6 +777,16 @@ func (p *Parser) registerExtension(a *obj.Addr, name string, prefix rune) { } } +// qualifySymbol returns name as a package-qualified symbol name. If +// name starts with a period, qualifySymbol prepends the package +// prefix. Otherwise it returns name unchanged. +func (p *Parser) qualifySymbol(name string) string { + if strings.HasPrefix(name, ".") { + name = p.pkgPrefix + name + } + return name +} + // symbolReference parses a symbol that is known not to be a register. func (p *Parser) symbolReference(a *obj.Addr, name string, prefix rune) { // Identifier is a name. @@ -864,7 +882,7 @@ func (p *Parser) symRefAttrs(name string, issueError bool) (bool, obj.ABI) { isStatic = true } else if tok == scanner.Ident { abistr := p.get(scanner.Ident).String() - if !p.compilingRuntime { + if !p.allowABI { if issueError { p.errorf("ABI selector only permitted when compiling runtime, reference was to %q", name) } @@ -901,6 +919,7 @@ func (p *Parser) funcAddress() (string, obj.ABI, bool) { if tok.ScanToken != scanner.Ident || p.atStartOfRegister(name) { return "", obj.ABI0, false } + name = p.qualifySymbol(name) // Parse optional <> (indicates a static symbol) or // <ABIxxx> (selecting text symbol with specific ABI). noErrMsg := false @@ -928,7 +947,7 @@ func (p *Parser) funcAddress() (string, obj.ABI, bool) { } // registerIndirect parses the general form of a register indirection. -// It is can be (R1), (R2*scale), (R1)(R2*scale), (R1)(R2.SXTX<<3) or (R1)(R2<<3) +// It can be (R1), (R2*scale), (R1)(R2*scale), (R1)(R2.SXTX<<3) or (R1)(R2<<3) // where R1 may be a simple register or register pair R:R or (R, R) or (R+R). // Or it might be a pseudo-indirection like (FP). // We are sitting on the opening parenthesis. @@ -1186,7 +1205,7 @@ func (p *Parser) registerListX86(a *obj.Addr) { a.Offset = x86.EncodeRegisterRange(lo, hi) } -// register number is ARM-specific. It returns the number of the specified register. +// registerNumber is ARM-specific. It returns the number of the specified register. func (p *Parser) registerNumber(name string) uint16 { if p.arch.Family == sys.ARM && name == "g" { return 10 diff --git a/src/cmd/asm/internal/asm/pseudo_test.go b/src/cmd/asm/internal/asm/pseudo_test.go index 5e6fcf8dfe..b9be6a7b2d 100644 --- a/src/cmd/asm/internal/asm/pseudo_test.go +++ b/src/cmd/asm/internal/asm/pseudo_test.go @@ -64,16 +64,16 @@ func TestErroneous(t *testing.T) { } testcats := []struct { - compilingRuntime bool - tests []errtest + allowABI bool + tests []errtest }{ { - compilingRuntime: false, - tests: nonRuntimeTests, + allowABI: false, + tests: nonRuntimeTests, }, { - compilingRuntime: true, - tests: runtimeTests, + allowABI: true, + tests: runtimeTests, }, } @@ -85,7 +85,7 @@ func TestErroneous(t *testing.T) { for _, cat := range testcats { for _, test := range cat.tests { - parser.compilingRuntime = cat.compilingRuntime + parser.allowABI = cat.allowABI parser.errorCount = 0 parser.lineNum++ if !parser.pseudo(test.pseudo, tokenize(test.operands)) { diff --git a/src/cmd/asm/internal/asm/testdata/arm.s b/src/cmd/asm/internal/asm/testdata/arm.s index 2ba22c71de..93edc8854e 100644 --- a/src/cmd/asm/internal/asm/testdata/arm.s +++ b/src/cmd/asm/internal/asm/testdata/arm.s @@ -870,10 +870,13 @@ jmp_label_3: BIC.S R0@>R1, R2 // 7021d2e1 // SRL + SRL $0, R5, R6 // 0560a0e1 + SRL $1, R5, R6 // a560a0e1 SRL $14, R5, R6 // 2567a0e1 SRL $15, R5, R6 // a567a0e1 SRL $30, R5, R6 // 256fa0e1 SRL $31, R5, R6 // a56fa0e1 + SRL $32, R5, R6 // 2560a0e1 SRL.S $14, R5, R6 // 2567b0e1 SRL.S $15, R5, R6 // a567b0e1 SRL.S $30, R5, R6 // 256fb0e1 @@ -892,10 +895,13 @@ jmp_label_3: SRL.S R5, R7 // 3775b0e1 // SRA + SRA $0, R5, R6 // 0560a0e1 + SRA $1, R5, R6 // c560a0e1 SRA $14, R5, R6 // 4567a0e1 SRA $15, R5, R6 // c567a0e1 SRA $30, R5, R6 // 456fa0e1 SRA $31, R5, R6 // c56fa0e1 + SRA $32, R5, R6 // 4560a0e1 SRA.S $14, R5, R6 // 4567b0e1 SRA.S $15, R5, R6 // c567b0e1 SRA.S $30, R5, R6 // 456fb0e1 @@ -914,6 +920,8 @@ jmp_label_3: SRA.S R5, R7 // 5775b0e1 // SLL + SLL $0, R5, R6 // 0560a0e1 + SLL $1, R5, R6 // 8560a0e1 SLL $14, R5, R6 // 0567a0e1 SLL $15, R5, R6 // 8567a0e1 SLL $30, R5, R6 // 056fa0e1 @@ -935,6 +943,20 @@ jmp_label_3: SLL R5, R7 // 1775a0e1 SLL.S R5, R7 // 1775b0e1 +// Ops with zero shifts should encode as left shifts + ADD R0<<0, R1, R2 // 002081e0 + ADD R0>>0, R1, R2 // 002081e0 + ADD R0->0, R1, R2 // 002081e0 + ADD R0@>0, R1, R2 // 002081e0 + MOVW R0<<0(R1), R2 // 002091e7 + MOVW R0>>0(R1), R2 // 002091e7 + MOVW R0->0(R1), R2 // 002091e7 + MOVW R0@>0(R1), R2 // 002091e7 + MOVW R0, R1<<0(R2) // 010082e7 + MOVW R0, R1>>0(R2) // 010082e7 + MOVW R0, R1->0(R2) // 010082e7 + MOVW R0, R1@>0(R2) // 010082e7 + // MULA / MULS MULAWT R1, R2, R3, R4 // c23124e1 MULAWB R1, R2, R3, R4 // 823124e1 diff --git a/src/cmd/asm/internal/asm/testdata/arm64.s b/src/cmd/asm/internal/asm/testdata/arm64.s index 11bd678552..ecad08b37a 100644 --- a/src/cmd/asm/internal/asm/testdata/arm64.s +++ b/src/cmd/asm/internal/asm/testdata/arm64.s @@ -557,37 +557,92 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8 FMOVQ 65520(R10), F10 // 4afdff3d FMOVQ 64(RSP), F11 // eb13c03d -// large aligned offset, use two instructions(add+ldr/store). - MOVB R1, 0x1001(R2) // MOVB R1, 4097(R2) // 5b04409161070039 - MOVH R1, 0x2002(R2) // MOVH R1, 8194(R2) // 5b08409161070079 - MOVW R1, 0x4004(R2) // MOVW R1, 16388(R2) // 5b104091610700b9 - MOVD R1, 0x8008(R2) // MOVD R1, 32776(R2) // 5b204091610700f9 - FMOVS F1, 0x4004(R2) // FMOVS F1, 16388(R2) // 5b104091610700bd - FMOVD F1, 0x8008(R2) // FMOVD F1, 32776(R2) // 5b204091610700fd +// medium offsets that either fit a single instruction or can use add+ldr/str + MOVD -4095(R17), R3 // 3bfe3fd1630340f9 + MOVD -391(R17), R3 // 3b1e06d1630340f9 + MOVD -257(R17), R3 // 3b0604d1630340f9 + MOVD -256(R17), R3 // 230250f8 + MOVD 255(R17), R3 // 23f24ff8 + MOVD 256(R17), R3 // 238240f9 + MOVD 257(R17), R3 // 3b060491630340f9 + MOVD 391(R17), R3 // 3b1e0691630340f9 + MOVD 4095(R17), R3 // 3bfe3f91630340f9 - MOVB 0x1001(R1), R2 // MOVB 4097(R1), R2 // 3b04409162078039 - MOVH 0x2002(R1), R2 // MOVH 8194(R1), R2 // 3b08409162078079 - MOVW 0x4004(R1), R2 // MOVW 16388(R1), R2 // 3b104091620780b9 - MOVD 0x8008(R1), R2 // MOVD 32776(R1), R2 // 3b204091620740f9 - FMOVS 0x4004(R1), F2 // FMOVS 16388(R1), F2 // 3b104091620740bd - FMOVD 0x8008(R1), F2 // FMOVD 32776(R1), F2 // 3b204091620740fd + MOVD R0, -4095(R17) // 3bfe3fd1600300f9 + MOVD R0, -391(R17) // 3b1e06d1600300f9 + MOVD R0, -257(R17) // 3b0604d1600300f9 + MOVD R0, -256(R17) // 200210f8 + MOVD R0, 255(R17) // 20f20ff8 + MOVD R0, 256(R17) // 208200f9 + MOVD R0, 257(R17) // 3b060491600300f9 + MOVD R0, 391(R17) // 3b1e0691600300f9 + MOVD R0, 4095(R17) // 3bfe3f91600300f9 + MOVD R0, 4096(R17) // 200208f9 + MOVD R3, -4095(R17) // 3bfe3fd1630300f9 + MOVD R3, -391(R17) // 3b1e06d1630300f9 + MOVD R3, -257(R17) // 3b0604d1630300f9 + MOVD R3, -256(R17) // 230210f8 + MOVD R3, 255(R17) // 23f20ff8 + MOVD R3, 256(R17) // 238200f9 + MOVD R3, 257(R17) // 3b060491630300f9 + MOVD R3, 391(R17) // 3b1e0691630300f9 + MOVD R3, 4095(R17) // 3bfe3f91630300f9 + +// large aligned offset, use two instructions(add+ldr/str). + MOVB R1, 0x1001(R2) // MOVB R1, 4097(R2) // 5b04409161070039 + MOVB R1, 0xffffff(R2) // MOVB R1, 16777215(R2) // 5bfc7f9161ff3f39 + MOVH R1, 0x2002(R2) // MOVH R1, 8194(R2) // 5b08409161070079 + MOVH R1, 0x1000ffe(R2) // MOVH R1, 16781310(R2) // 5bfc7f9161ff3f79 + MOVW R1, 0x4004(R2) // MOVW R1, 16388(R2) // 5b104091610700b9 + MOVW R1, 0x1002ffc(R2) // MOVW R1, 16789500(R2) // 5bfc7f9161ff3fb9 + MOVD R1, 0x8008(R2) // MOVD R1, 32776(R2) // 5b204091610700f9 + MOVD R1, 0x1006ff8(R2) // MOVD R1, 16805880(R2) // 5bfc7f9161ff3ff9 + FMOVS F1, 0x4004(R2) // FMOVS F1, 16388(R2) // 5b104091610700bd + FMOVS F1, 0x1002ffc(R2) // FMOVS F1, 16789500(R2) // 5bfc7f9161ff3fbd + FMOVD F1, 0x8008(R2) // FMOVD F1, 32776(R2) // 5b204091610700fd + FMOVD F1, 0x1006ff8(R2) // FMOVD F1, 16805880(R2) // 5bfc7f9161ff3ffd + + MOVB 0x1001(R1), R2 // MOVB 4097(R1), R2 // 3b04409162078039 + MOVB 0xffffff(R1), R2 // MOVB 16777215(R1), R2 // 3bfc7f9162ffbf39 + MOVH 0x2002(R1), R2 // MOVH 8194(R1), R2 // 3b08409162078079 + MOVH 0x1000ffe(R1), R2 // MOVH 16781310(R1), R2 // 3bfc7f9162ffbf79 + MOVW 0x4004(R1), R2 // MOVW 16388(R1), R2 // 3b104091620780b9 + MOVW 0x1002ffc(R1), R2 // MOVW 16789500(R1), R2 // 3bfc7f9162ffbfb9 + MOVD 0x8008(R1), R2 // MOVD 32776(R1), R2 // 3b204091620740f9 + MOVD 0x1006ff8(R1), R2 // MOVD 16805880(R1), R2 // 3bfc7f9162ff7ff9 + FMOVS 0x4004(R1), F2 // FMOVS 16388(R1), F2 // 3b104091620740bd + FMOVS 0x1002ffc(R1), F2 // FMOVS 16789500(R1), F2 // 3bfc7f9162ff7fbd + FMOVD 0x8008(R1), F2 // FMOVD 32776(R1), F2 // 3b204091620740fd + FMOVD 0x1006ff8(R1), F2 // FMOVD 16805880(R1), F2 // 3bfc7f9162ff7ffd // very large or unaligned offset uses constant pool. // the encoding cannot be checked as the address of the constant pool is unknown. // here we only test that they can be assembled. - MOVB R1, 0x44332211(R2) // MOVB R1, 1144201745(R2) - MOVH R1, 0x44332211(R2) // MOVH R1, 1144201745(R2) - MOVW R1, 0x44332211(R2) // MOVW R1, 1144201745(R2) - MOVD R1, 0x44332211(R2) // MOVD R1, 1144201745(R2) - FMOVS F1, 0x44332211(R2) // FMOVS F1, 1144201745(R2) - FMOVD F1, 0x44332211(R2) // FMOVD F1, 1144201745(R2) + MOVB R1, 0x1000000(R2) // MOVB R1, 16777216(R2) + MOVB R1, 0x44332211(R2) // MOVB R1, 1144201745(R2) + MOVH R1, 0x1001000(R2) // MOVH R1, 16781312(R2) + MOVH R1, 0x44332211(R2) // MOVH R1, 1144201745(R2) + MOVW R1, 0x1003000(R2) // MOVW R1, 16789504(R2) + MOVW R1, 0x44332211(R2) // MOVW R1, 1144201745(R2) + MOVD R1, 0x1007000(R2) // MOVD R1, 16805888(R2) + MOVD R1, 0x44332211(R2) // MOVD R1, 1144201745(R2) + FMOVS F1, 0x1003000(R2) // FMOVS F1, 16789504(R2) + FMOVS F1, 0x44332211(R2) // FMOVS F1, 1144201745(R2) + FMOVD F1, 0x1007000(R2) // FMOVD F1, 16805888(R2) + FMOVD F1, 0x44332211(R2) // FMOVD F1, 1144201745(R2) - MOVB 0x44332211(R1), R2 // MOVB 1144201745(R1), R2 - MOVH 0x44332211(R1), R2 // MOVH 1144201745(R1), R2 - MOVW 0x44332211(R1), R2 // MOVW 1144201745(R1), R2 - MOVD 0x44332211(R1), R2 // MOVD 1144201745(R1), R2 - FMOVS 0x44332211(R1), F2 // FMOVS 1144201745(R1), F2 - FMOVD 0x44332211(R1), F2 // FMOVD 1144201745(R1), F2 + MOVB 0x1000000(R1), R2 // MOVB 16777216(R1), R2 + MOVB 0x44332211(R1), R2 // MOVB 1144201745(R1), R2 + MOVH 0x1000000(R1), R2 // MOVH 16777216(R1), R2 + MOVH 0x44332211(R1), R2 // MOVH 1144201745(R1), R2 + MOVW 0x1000000(R1), R2 // MOVW 16777216(R1), R2 + MOVW 0x44332211(R1), R2 // MOVW 1144201745(R1), R2 + MOVD 0x1000000(R1), R2 // MOVD 16777216(R1), R2 + MOVD 0x44332211(R1), R2 // MOVD 1144201745(R1), R2 + FMOVS 0x1000000(R1), F2 // FMOVS 16777216(R1), F2 + FMOVS 0x44332211(R1), F2 // FMOVS 1144201745(R1), F2 + FMOVD 0x1000000(R1), F2 // FMOVD 16777216(R1), F2 + FMOVD 0x44332211(R1), F2 // FMOVD 1144201745(R1), F2 // shifted or extended register offset. MOVD (R2)(R6.SXTW), R4 // 44c866f8 @@ -595,6 +650,7 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8 MOVD (R3)(R6*1), R5 // 656866f8 MOVD (R2)(R6), R4 // 446866f8 MOVWU (R19)(R20<<2), R20 // 747a74b8 + MOVD (R2)(R3<<0), R1 // 416863f8 MOVD (R2)(R6<<3), R4 // 447866f8 MOVD (R3)(R7.SXTX<<3), R8 // 68f867f8 MOVWU (R5)(R4.UXTW), R10 // aa4864b8 @@ -604,7 +660,7 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8 MOVHU (R1)(R2<<1), R5 // 25786278 MOVB (R9)(R3.UXTW), R6 // 2649a338 MOVB (R10)(R6), R15 // 4f69a638 - MOVB (R29)(R30<<0), R14 // ae7bbe38 + MOVB (R29)(R30<<0), R14 // ae6bbe38 MOVB (R29)(R30), R14 // ae6bbe38 MOVH (R5)(R7.SXTX<<1), R19 // b3f8a778 MOVH (R8)(R4<<1), R10 // 0a79a478 @@ -925,6 +981,14 @@ again: ADR next, R11 // ADR R11 // 2b000010 next: NOP + ADR -2(PC), R10 // 0a000010 + ADR 2(PC), R16 // 10000010 + ADR -26(PC), R1 // 01000010 + ADR 12(PC), R2 // 02000010 + ADRP -2(PC), R10 // 0a000090 + ADRP 2(PC), R16 // 10000090 + ADRP -26(PC), R1 // 01000090 + ADRP 12(PC), R2 // 02000090 // LDP/STP LDP (R0), (R0, R1) // 000440a9 @@ -947,6 +1011,7 @@ next: LDP -8(R0), (R1, R2) // 01887fa9 LDP x(SB), (R1, R2) LDP x+8(SB), (R1, R2) + LDP 8(R1), (ZR, R2) // 3f8840a9 LDPW -5(R0), (R1, R2) // 1b1400d1610b4029 LDPW (R0), (R1, R2) // 01084029 LDPW 4(R0), (R1, R2) // 01884029 @@ -964,6 +1029,7 @@ next: LDPW 1024(RSP), (R1, R2) // fb031091610b4029 LDPW x(SB), (R1, R2) LDPW x+8(SB), (R1, R2) + LDPW 8(R1), (ZR, R2) // 3f084129 LDPSW (R0), (R1, R2) // 01084069 LDPSW 4(R0), (R1, R2) // 01884069 LDPSW -4(R0), (R1, R2) // 01887f69 @@ -980,6 +1046,7 @@ next: LDPSW 1024(RSP), (R1, R2) // fb031091610b4069 LDPSW x(SB), (R1, R2) LDPSW x+8(SB), (R1, R2) + LDPSW 8(R1), (ZR, R2) // 3f084169 STP (R3, R4), (R5) // a31000a9 STP (R3, R4), 8(R5) // a39000a9 STP.W (R3, R4), 8(R5) // a39080a9 diff --git a/src/cmd/asm/internal/asm/testdata/arm64enc.s b/src/cmd/asm/internal/asm/testdata/arm64enc.s index 7ef3a7f5f0..cc002a1584 100644 --- a/src/cmd/asm/internal/asm/testdata/arm64enc.s +++ b/src/cmd/asm/internal/asm/testdata/arm64enc.s @@ -186,7 +186,7 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$-8 MOVBU.P 42(R2), R12 // 4ca44238 MOVBU.W -27(R2), R14 // 4e5c5e38 MOVBU 2916(R24), R3 // 03936d39 - MOVBU (R19)(R14<<0), R23 // 777a6e38 + MOVBU (R19)(R14<<0), R23 // 776a6e38 MOVBU (R2)(R8.SXTX), R19 // 53e86838 MOVBU (R27)(R23), R14 // 6e6b7738 MOVHU.P 107(R14), R13 // cdb54678 diff --git a/src/cmd/asm/internal/asm/testdata/arm64error.s b/src/cmd/asm/internal/asm/testdata/arm64error.s index 354b64df02..3ac8788424 100644 --- a/src/cmd/asm/internal/asm/testdata/arm64error.s +++ b/src/cmd/asm/internal/asm/testdata/arm64error.s @@ -66,7 +66,6 @@ TEXT errors(SB),$0 LDP.W 8(R3), (R2, R3) // ERROR "constrained unpredictable behavior" LDP (R1), (R2, R2) // ERROR "constrained unpredictable behavior" LDP (R0), (F0, F1) // ERROR "invalid register pair" - LDP (R0), (R3, ZR) // ERROR "invalid register pair" LDXPW (RSP), (R2, R2) // ERROR "constrained unpredictable behavior" LDAXPW (R5), (R2, R2) // ERROR "constrained unpredictable behavior" MOVD.P 300(R2), R3 // ERROR "offset out of range [-256,255]" @@ -166,94 +165,94 @@ TEXT errors(SB),$0 FSTPD (R1, R2), (R0) // ERROR "invalid register pair" FMOVS (F2), F0 // ERROR "illegal combination" FMOVD F0, (F1) // ERROR "illegal combination" - LDADDAD R5, (R6), RSP // ERROR "illegal destination register" - LDADDAW R5, (R6), RSP // ERROR "illegal destination register" - LDADDAH R5, (R6), RSP // ERROR "illegal destination register" - LDADDAB R5, (R6), RSP // ERROR "illegal destination register" - LDADDALD R5, (R6), RSP // ERROR "illegal destination register" - LDADDALW R5, (R6), RSP // ERROR "illegal destination register" - LDADDALH R5, (R6), RSP // ERROR "illegal destination register" - LDADDALB R5, (R6), RSP // ERROR "illegal destination register" - LDADDD R5, (R6), RSP // ERROR "illegal destination register" - LDADDW R5, (R6), RSP // ERROR "illegal destination register" - LDADDH R5, (R6), RSP // ERROR "illegal destination register" - LDADDB R5, (R6), RSP // ERROR "illegal destination register" - LDADDLD R5, (R6), RSP // ERROR "illegal destination register" - LDADDLW R5, (R6), RSP // ERROR "illegal destination register" - LDADDLH R5, (R6), RSP // ERROR "illegal destination register" - LDADDLB R5, (R6), RSP // ERROR "illegal destination register" - LDCLRAD R5, (R6), RSP // ERROR "illegal destination register" - LDCLRAW R5, (R6), RSP // ERROR "illegal destination register" - LDCLRAH R5, (R6), RSP // ERROR "illegal destination register" - LDCLRAB R5, (R6), RSP // ERROR "illegal destination register" - LDCLRALD R5, (R6), RSP // ERROR "illegal destination register" - LDCLRALW R5, (R6), RSP // ERROR "illegal destination register" - LDCLRALH R5, (R6), RSP // ERROR "illegal destination register" - LDCLRALB R5, (R6), RSP // ERROR "illegal destination register" - LDCLRD R5, (R6), RSP // ERROR "illegal destination register" - LDCLRW R5, (R6), RSP // ERROR "illegal destination register" - LDCLRH R5, (R6), RSP // ERROR "illegal destination register" - LDCLRB R5, (R6), RSP // ERROR "illegal destination register" - LDCLRLD R5, (R6), RSP // ERROR "illegal destination register" - LDCLRLW R5, (R6), RSP // ERROR "illegal destination register" - LDCLRLH R5, (R6), RSP // ERROR "illegal destination register" - LDCLRLB R5, (R6), RSP // ERROR "illegal destination register" - LDEORAD R5, (R6), RSP // ERROR "illegal destination register" - LDEORAW R5, (R6), RSP // ERROR "illegal destination register" - LDEORAH R5, (R6), RSP // ERROR "illegal destination register" - LDEORAB R5, (R6), RSP // ERROR "illegal destination register" - LDEORALD R5, (R6), RSP // ERROR "illegal destination register" - LDEORALW R5, (R6), RSP // ERROR "illegal destination register" - LDEORALH R5, (R6), RSP // ERROR "illegal destination register" - LDEORALB R5, (R6), RSP // ERROR "illegal destination register" - LDEORD R5, (R6), RSP // ERROR "illegal destination register" - LDEORW R5, (R6), RSP // ERROR "illegal destination register" - LDEORH R5, (R6), RSP // ERROR "illegal destination register" - LDEORB R5, (R6), RSP // ERROR "illegal destination register" - LDEORLD R5, (R6), RSP // ERROR "illegal destination register" - LDEORLW R5, (R6), RSP // ERROR "illegal destination register" - LDEORLH R5, (R6), RSP // ERROR "illegal destination register" - LDEORLB R5, (R6), RSP // ERROR "illegal destination register" - LDORAD R5, (R6), RSP // ERROR "illegal destination register" - LDORAW R5, (R6), RSP // ERROR "illegal destination register" - LDORAH R5, (R6), RSP // ERROR "illegal destination register" - LDORAB R5, (R6), RSP // ERROR "illegal destination register" - LDORALD R5, (R6), RSP // ERROR "illegal destination register" - LDORALW R5, (R6), RSP // ERROR "illegal destination register" - LDORALH R5, (R6), RSP // ERROR "illegal destination register" - LDORALB R5, (R6), RSP // ERROR "illegal destination register" - LDORD R5, (R6), RSP // ERROR "illegal destination register" - LDORW R5, (R6), RSP // ERROR "illegal destination register" - LDORH R5, (R6), RSP // ERROR "illegal destination register" - LDORB R5, (R6), RSP // ERROR "illegal destination register" - LDORLD R5, (R6), RSP // ERROR "illegal destination register" - LDORLW R5, (R6), RSP // ERROR "illegal destination register" - LDORLH R5, (R6), RSP // ERROR "illegal destination register" - LDORLB R5, (R6), RSP // ERROR "illegal destination register" - SWPAD R5, (R6), RSP // ERROR "illegal destination register" - SWPAW R5, (R6), RSP // ERROR "illegal destination register" - SWPAH R5, (R6), RSP // ERROR "illegal destination register" - SWPAB R5, (R6), RSP // ERROR "illegal destination register" - SWPALD R5, (R6), RSP // ERROR "illegal destination register" - SWPALW R5, (R6), RSP // ERROR "illegal destination register" - SWPALH R5, (R6), RSP // ERROR "illegal destination register" - SWPALB R5, (R6), RSP // ERROR "illegal destination register" - SWPD R5, (R6), RSP // ERROR "illegal destination register" - SWPW R5, (R6), RSP // ERROR "illegal destination register" - SWPH R5, (R6), RSP // ERROR "illegal destination register" - SWPB R5, (R6), RSP // ERROR "illegal destination register" - SWPLD R5, (R6), RSP // ERROR "illegal destination register" - SWPLW R5, (R6), RSP // ERROR "illegal destination register" - SWPLH R5, (R6), RSP // ERROR "illegal destination register" - SWPLB R5, (R6), RSP // ERROR "illegal destination register" - STXR R5, (R6), RSP // ERROR "illegal destination register" - STXRW R5, (R6), RSP // ERROR "illegal destination register" - STLXR R5, (R6), RSP // ERROR "illegal destination register" - STLXRW R5, (R6), RSP // ERROR "illegal destination register" - STXP (R5, R7), (R6), RSP // ERROR "illegal destination register" - STXPW (R5, R7), (R6), RSP // ERROR "illegal destination register" - STLXP (R5, R7), (R6), RSP // ERROR "illegal destination register" - STLXP (R5, R7), (R6), RSP // ERROR "illegal destination register" + LDADDAD R5, (R6), RSP // ERROR "illegal combination" + LDADDAW R5, (R6), RSP // ERROR "illegal combination" + LDADDAH R5, (R6), RSP // ERROR "illegal combination" + LDADDAB R5, (R6), RSP // ERROR "illegal combination" + LDADDALD R5, (R6), RSP // ERROR "illegal combination" + LDADDALW R5, (R6), RSP // ERROR "illegal combination" + LDADDALH R5, (R6), RSP // ERROR "illegal combination" + LDADDALB R5, (R6), RSP // ERROR "illegal combination" + LDADDD R5, (R6), RSP // ERROR "illegal combination" + LDADDW R5, (R6), RSP // ERROR "illegal combination" + LDADDH R5, (R6), RSP // ERROR "illegal combination" + LDADDB R5, (R6), RSP // ERROR "illegal combination" + LDADDLD R5, (R6), RSP // ERROR "illegal combination" + LDADDLW R5, (R6), RSP // ERROR "illegal combination" + LDADDLH R5, (R6), RSP // ERROR "illegal combination" + LDADDLB R5, (R6), RSP // ERROR "illegal combination" + LDCLRAD R5, (R6), RSP // ERROR "illegal combination" + LDCLRAW R5, (R6), RSP // ERROR "illegal combination" + LDCLRAH R5, (R6), RSP // ERROR "illegal combination" + LDCLRAB R5, (R6), RSP // ERROR "illegal combination" + LDCLRALD R5, (R6), RSP // ERROR "illegal combination" + LDCLRALW R5, (R6), RSP // ERROR "illegal combination" + LDCLRALH R5, (R6), RSP // ERROR "illegal combination" + LDCLRALB R5, (R6), RSP // ERROR "illegal combination" + LDCLRD R5, (R6), RSP // ERROR "illegal combination" + LDCLRW R5, (R6), RSP // ERROR "illegal combination" + LDCLRH R5, (R6), RSP // ERROR "illegal combination" + LDCLRB R5, (R6), RSP // ERROR "illegal combination" + LDCLRLD R5, (R6), RSP // ERROR "illegal combination" + LDCLRLW R5, (R6), RSP // ERROR "illegal combination" + LDCLRLH R5, (R6), RSP // ERROR "illegal combination" + LDCLRLB R5, (R6), RSP // ERROR "illegal combination" + LDEORAD R5, (R6), RSP // ERROR "illegal combination" + LDEORAW R5, (R6), RSP // ERROR "illegal combination" + LDEORAH R5, (R6), RSP // ERROR "illegal combination" + LDEORAB R5, (R6), RSP // ERROR "illegal combination" + LDEORALD R5, (R6), RSP // ERROR "illegal combination" + LDEORALW R5, (R6), RSP // ERROR "illegal combination" + LDEORALH R5, (R6), RSP // ERROR "illegal combination" + LDEORALB R5, (R6), RSP // ERROR "illegal combination" + LDEORD R5, (R6), RSP // ERROR "illegal combination" + LDEORW R5, (R6), RSP // ERROR "illegal combination" + LDEORH R5, (R6), RSP // ERROR "illegal combination" + LDEORB R5, (R6), RSP // ERROR "illegal combination" + LDEORLD R5, (R6), RSP // ERROR "illegal combination" + LDEORLW R5, (R6), RSP // ERROR "illegal combination" + LDEORLH R5, (R6), RSP // ERROR "illegal combination" + LDEORLB R5, (R6), RSP // ERROR "illegal combination" + LDORAD R5, (R6), RSP // ERROR "illegal combination" + LDORAW R5, (R6), RSP // ERROR "illegal combination" + LDORAH R5, (R6), RSP // ERROR "illegal combination" + LDORAB R5, (R6), RSP // ERROR "illegal combination" + LDORALD R5, (R6), RSP // ERROR "illegal combination" + LDORALW R5, (R6), RSP // ERROR "illegal combination" + LDORALH R5, (R6), RSP // ERROR "illegal combination" + LDORALB R5, (R6), RSP // ERROR "illegal combination" + LDORD R5, (R6), RSP // ERROR "illegal combination" + LDORW R5, (R6), RSP // ERROR "illegal combination" + LDORH R5, (R6), RSP // ERROR "illegal combination" + LDORB R5, (R6), RSP // ERROR "illegal combination" + LDORLD R5, (R6), RSP // ERROR "illegal combination" + LDORLW R5, (R6), RSP // ERROR "illegal combination" + LDORLH R5, (R6), RSP // ERROR "illegal combination" + LDORLB R5, (R6), RSP // ERROR "illegal combination" + SWPAD R5, (R6), RSP // ERROR "illegal combination" + SWPAW R5, (R6), RSP // ERROR "illegal combination" + SWPAH R5, (R6), RSP // ERROR "illegal combination" + SWPAB R5, (R6), RSP // ERROR "illegal combination" + SWPALD R5, (R6), RSP // ERROR "illegal combination" + SWPALW R5, (R6), RSP // ERROR "illegal combination" + SWPALH R5, (R6), RSP // ERROR "illegal combination" + SWPALB R5, (R6), RSP // ERROR "illegal combination" + SWPD R5, (R6), RSP // ERROR "illegal combination" + SWPW R5, (R6), RSP // ERROR "illegal combination" + SWPH R5, (R6), RSP // ERROR "illegal combination" + SWPB R5, (R6), RSP // ERROR "illegal combination" + SWPLD R5, (R6), RSP // ERROR "illegal combination" + SWPLW R5, (R6), RSP // ERROR "illegal combination" + SWPLH R5, (R6), RSP // ERROR "illegal combination" + SWPLB R5, (R6), RSP // ERROR "illegal combination" + STXR R5, (R6), RSP // ERROR "illegal combination" + STXRW R5, (R6), RSP // ERROR "illegal combination" + STLXR R5, (R6), RSP // ERROR "illegal combination" + STLXRW R5, (R6), RSP // ERROR "illegal combination" + STXP (R5, R7), (R6), RSP // ERROR "illegal combination" + STXPW (R5, R7), (R6), RSP // ERROR "illegal combination" + STLXP (R5, R7), (R6), RSP // ERROR "illegal combination" + STLXP (R5, R7), (R6), RSP // ERROR "illegal combination" MSR OSLAR_EL1, R5 // ERROR "illegal combination" MRS R11, AIDR_EL1 // ERROR "illegal combination" MSR R6, AIDR_EL1 // ERROR "system register is not writable" diff --git a/src/cmd/asm/internal/asm/testdata/mips.s b/src/cmd/asm/internal/asm/testdata/mips.s index 7136d686d7..f65eba07ba 100644 --- a/src/cmd/asm/internal/asm/testdata/mips.s +++ b/src/cmd/asm/internal/asm/testdata/mips.s @@ -429,6 +429,11 @@ label4: CLZ R1, R2 // 70221020 CLO R1, R2 // 70221021 + WSBH R1, R2 // 7c0110a0 + + SEB R1, R2 // 7c011420 + SEH R1, R2 // 7c011620 + // to (Hi, Lo) MADD R2, R1 // 70220000 MSUB R2, R1 // 70220004 diff --git a/src/cmd/asm/internal/asm/testdata/mips64.s b/src/cmd/asm/internal/asm/testdata/mips64.s index 8f628e26c9..ea4bb80aec 100644 --- a/src/cmd/asm/internal/asm/testdata/mips64.s +++ b/src/cmd/asm/internal/asm/testdata/mips64.s @@ -587,8 +587,17 @@ label4: CALL foo(SB) RET foo(SB) + // unary operation NEGW R1, R2 // 00011023 NEGV R1, R2 // 0001102f + + WSBH R1, R2 // 7c0110a0 + DSBH R1, R2 // 7c0110a4 + DSHD R1, R2 // 7c011164 + + SEB R1, R2 // 7c011420 + SEH R1, R2 // 7c011620 + RET // MSA VMOVI diff --git a/src/cmd/asm/internal/asm/testdata/ppc64.s b/src/cmd/asm/internal/asm/testdata/ppc64.s index a0f1276aa1..01052b49e7 100644 --- a/src/cmd/asm/internal/asm/testdata/ppc64.s +++ b/src/cmd/asm/internal/asm/testdata/ppc64.s @@ -17,14 +17,14 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 MOVD $1, R3 // 38600001 MOVD $-1, R4 // 3880ffff MOVD $65535, R5 // 6005ffff - MOVD $65536, R6 // 64060001 + MOVD $65536, R6 // 3cc00001 MOVD $-32767, R5 // 38a08001 MOVD $-32768, R6 // 38c08000 MOVD $1234567, R5 // 6405001260a5d687 or 0600001238a0d687 MOVW $1, R3 // 38600001 MOVW $-1, R4 // 3880ffff MOVW $65535, R5 // 6005ffff - MOVW $65536, R6 // 64060001 + MOVW $65536, R6 // 3cc00001 MOVW $-32767, R5 // 38a08001 MOVW $-32768, R6 // 38c08000 MOVW $1234567, R5 // 6405001260a5d687 or 0600001238a0d687 @@ -32,7 +32,26 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 MOVW $2147483649, R5 // 6405800060a50001 or 0600800038a00001 MOVD $2147483649, R5 // 6405800060a50001 or 0600800038a00001 // Hex constant 0xFFFFFFFF80000001 - MOVD $-2147483647, R5 // 3ca0800060a50001 or 0603800038a00001 + MOVD $-2147483647, R5 // 3ca0800060a50001 or 0603800038a00001 + // Hex constant 0xFFFFFFFE00000002 (load of constant on < power10, pli on >= power10 + MOVD $-8589934590, R5 // 3ca00000e8a50000 or 0602000038a00002 + + // For backwards compatibility, MOVW $const,Rx and MOVWZ $const,Rx assemble identically + // and accept the same constants. + MOVW $2147483648, R5 // 64058000 + MOVWZ $-2147483648, R5 // 3ca08000 + + // TODO: These are preprocessed by the assembler into MOVD $const>>shift, R5; SLD $shift, R5. + // This only captures the MOVD. Should the SLD be appended to the encoding by the test? + // Hex constant 0x20004000000 + MOVD $2199090364416, R5 // 60058001 + // Hex constant 0xFFFFFE0004000000 + MOVD $-2198956146688, R5 // 38a08001 + // TODO: On GOPPC64={power8,power9}, this is preprocessed into MOVD $-1, R5; RLDC R5, $33, $63, R5. + // This only captures the MOVD. Should the RLDC be appended to the encoding by the test? + // Hex constant 0xFFFFFFFE00000001 + MOVD $-8589934591, R5 // 38a0ffff or 0602000038a00001 + MOVD 8(R3), R4 // e8830008 MOVD (R3)(R4), R5 // 7ca4182a MOVD (R3)(R0), R5 // 7ca0182a @@ -164,6 +183,10 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 ADD $-32767, R5, R4 // 38858001 ADD $-32768, R6 // 38c68000 ADD $-32768, R6, R5 // 38a68000 + // Hex constant 0xFFFFFFFE00000000 + ADD $-8589934592, R5 // 3fe0fffe600000007bff83e4600000007cbf2a14 or 0602000038a50000 + // Hex constant 0xFFFFFFFE00010001 + ADD $-8589869055, R5 // 3fe0fffe63ff00017bff83e463ff00017cbf2a14 or 0602000138a50001 //TODO: this compiles to add r5,r6,r0. It should be addi r5,r6,0. // this is OK since r0 == $0, but the latter is preferred. @@ -174,6 +197,7 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 ADDEX R3, R5, $3, R6 // 7cc32f54 ADDEX R3, $3, R5, R6 // 7cc32f54 ADDIS $8, R3 // 3c630008 + ADD $524288, R3 // 3c630008 ADDIS $1000, R3, R4 // 3c8303e8 ANDCC $1, R3 // 70630001 @@ -192,6 +216,7 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 ANDCC $1234567, R5, R6 // 641f001263ffd6877fe62839 ANDISCC $1, R3 // 74630001 ANDISCC $1000, R3, R4 // 746403e8 + ANDCC $65536000, R3, R4 // 746403e8 OR $1, R3 // 60630001 OR $1, R3, R4 // 60640001 @@ -207,7 +232,10 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 OR $-32768, R6, R7 // 3be080007fe73378 OR $1234567, R5 // 641f001263ffd6877fe52b78 OR $1234567, R5, R3 // 641f001263ffd6877fe32b78 - ORIS $255, R3, R4 + OR $2147483648, R5, R3 // 64a38000 + OR $2147483649, R5, R3 // 641f800063ff00017fe32b78 + ORIS $255, R3, R4 // 646400ff + OR $16711680, R3, R4 // 646400ff XOR $1, R3 // 68630001 XOR $1, R3, R4 // 68640001 @@ -223,7 +251,8 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 XOR $-32768, R6, R7 // 3be080007fe73278 XOR $1234567, R5 // 641f001263ffd6877fe52a78 XOR $1234567, R5, R3 // 641f001263ffd6877fe32a78 - XORIS $15, R3, R4 + XORIS $15, R3, R4 // 6c64000f + XOR $983040, R3, R4 // 6c64000f // TODO: the order of CR operands don't match CMP R3, R4 // 7c232000 @@ -233,7 +262,6 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 CMPB R3,R4,R4 // 7c6423f8 CMPEQB R3,R4,CR6 // 7f0321c0 - // TODO: constants for ADDC? ADD R3, R4 // 7c841a14 ADD R3, R4, R5 // 7ca41a14 ADDC R3, R4 // 7c841814 @@ -246,6 +274,8 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 ADDV R3, R4 // 7c841e14 ADDVCC R3, R4 // 7c841e15 ADDCCC R3, R4, R5 // 7ca41815 + ADDCCC $65536, R4, R5 // 641f0001600000007cbf2015 + ADDCCC $65537, R4, R5 // 641f000163ff00017cbf2015 ADDME R3, R4 // 7c8301d4 ADDMECC R3, R4 // 7c8301d5 ADDMEV R3, R4 // 7c8305d4 @@ -299,6 +329,8 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 SUBECC R3, R4, R5 // 7ca32111 SUBEV R3, R4, R5 // 7ca32510 SUBEVCC R3, R4, R5 // 7ca32511 + SUBC R3, $65536, R4 // 3fe00001600000007c83f810 + SUBC R3, $65537, R4 // 3fe0000163ff00017c83f810 MULLW R3, R4 // 7c8419d6 MULLW R3, R4, R5 // 7ca419d6 @@ -393,12 +425,19 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 EXTSHCC R3, R4 // 7c640735 EXTSW R3, R4 // 7c6407b4 EXTSWCC R3, R4 // 7c6407b5 + RLWMI $7, R3, $4026531855, R6 // 50663f06 + RLWMI $7, R3, $1, R6 // 50663ffe + RLWMI $7, R3, $2147483648, R6 // 50663800 RLWMI $7, R3, $65535, R6 // 50663c3e RLWMI $7, R3, $16, $31, R6 // 50663c3e RLWMICC $7, R3, $65535, R6 // 50663c3f RLWMICC $7, R3, $16, $31, R6 // 50663c3f RLWNM $3, R4, $7, R6 // 54861f7e + RLWNM $0, R4, $7, R6 // 5486077e + RLWNM R0, R4, $7, R6 // 5c86077e RLWNM $3, R4, $29, $31, R6 // 54861f7e + RLWNM $0, R4, $29, $31, R6 // 5486077e + RLWNM R0, R4, $29, $31, R6 // 5c86077e RLWNM R3, R4, $7, R6 // 5c861f7e RLWNM R3, R4, $29, $31, R6 // 5c861f7e RLWNMCC $3, R4, $7, R6 // 54861f7f @@ -410,6 +449,10 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 RLDIMI $0, R4, $7, R6 // 788601cc RLDIMICC $0, R4, $7, R6 // 788601cd RLDC $0, R4, $15, R6 // 78860728 + RLDC R3, $32, $12, R4 // 7864030a + RLDC R3, $8, $32, R4 // 78644028 + RLDCCC R3, $32, $12, R4 // 7864030b + RLDCCC R3, $8, $32, R4 // 78644029 RLDCCC $0, R4, $15, R6 // 78860729 RLDCL $0, R4, $7, R6 // 78860770 RLDCLCC $0, R4, $15, R6 // 78860721 diff --git a/src/cmd/asm/internal/asm/testdata/riscv64.s b/src/cmd/asm/internal/asm/testdata/riscv64.s index 53538320f0..072302b225 100644 --- a/src/cmd/asm/internal/asm/testdata/riscv64.s +++ b/src/cmd/asm/internal/asm/testdata/riscv64.s @@ -94,6 +94,10 @@ start: SUB X6, X5, X7 // b3836240 SUB X5, X6 // 33035340 + SUB $-2047, X5, X6 // 1383f27f + SUB $2048, X5, X6 // 13830280 + SUB $-2047, X5 // 9382f27f + SUB $2048, X5 // 93820280 SRA X6, X5, X7 // b3d36240 SRA X5, X6 // 33535340 @@ -157,6 +161,7 @@ start: ADDW $1, X6 // 1b031300 SLLW $1, X6 // 1b131300 SRLW $1, X6 // 1b531300 + SUBW $1, X6 // 1b03f3ff SRAW $1, X6 // 1b531340 // 5.3: Load and Store Instructions (RV64I) @@ -354,6 +359,14 @@ start: MOVD F0, 4(X5) // 27b20200 MOVD F0, F1 // d3000022 + // TLS load with local-exec (LUI + ADDIW + ADD of TP + load) + MOV tls(SB), X5 // b70f00009b8f0f00b38f4f0083b20f00 + MOVB tls(SB), X5 // b70f00009b8f0f00b38f4f0083820f00 + + // TLS store with local-exec (LUI + ADDIW + ADD of TP + store) + MOV X5, tls(SB) // b70f00009b8f0f00b38f4f0023b05f00 + MOVB X5, tls(SB) // b70f00009b8f0f00b38f4f0023805f00 + // NOT pseudo-instruction NOT X5 // 93c2f2ff NOT X5, X6 // 13c3f2ff @@ -373,7 +386,7 @@ start: JMP 4(X5) // 67804200 // CALL and JMP to symbol are encoded as JAL (using LR or ZERO - // respectively), with a R_RISCV_CALL relocation. The linker resolves + // respectively), with a R_RISCV_JAL relocation. The linker resolves // the real address and updates the immediate, using a trampoline in // the case where the address is not directly reachable. CALL asmtest(SB) // ef000000 @@ -407,3 +420,5 @@ start: FLTD F0, F1, X5 // d39200a2 FLED F0, F1, X5 // d38200a2 FEQD F0, F1, X5 // d3a200a2 + +GLOBL tls(SB), TLSBSS, $8 diff --git a/src/cmd/asm/internal/asm/testdata/riscv64error.s b/src/cmd/asm/internal/asm/testdata/riscv64error.s index cdb8a028bd..2dc9db3fb1 100644 --- a/src/cmd/asm/internal/asm/testdata/riscv64error.s +++ b/src/cmd/asm/internal/asm/testdata/riscv64error.s @@ -38,5 +38,8 @@ TEXT errors(SB),$0 SLLIW $-1, X5, X6 // ERROR "shift amount out of range 0 to 31" SRLIW $-1, X5, X6 // ERROR "shift amount out of range 0 to 31" SRAIW $-1, X5, X6 // ERROR "shift amount out of range 0 to 31" - + SD X5, 4294967296(X6) // ERROR "constant 4294967296 too large" + SRLI $1, X5, F1 // ERROR "expected integer register in rd position but got non-integer register F1" + SRLI $1, F1, X5 // ERROR "expected integer register in rs1 position but got non-integer register F1" + FNES F1, (X5) // ERROR "needs an integer register output" RET diff --git a/src/cmd/asm/internal/asm/testdata/s390x.s b/src/cmd/asm/internal/asm/testdata/s390x.s index 78ccb96fc1..977190678f 100644 --- a/src/cmd/asm/internal/asm/testdata/s390x.s +++ b/src/cmd/asm/internal/asm/testdata/s390x.s @@ -415,6 +415,14 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16- SYNC // 07e0 + KM R2, R4 // b92e0024 + KMC R2, R6 // b92f0026 + KLMD R2, R8 // b93f0028 + KIMD R0, R4 // b93e0004 + KDSA R0, R8 // b93a0008 + KMA R2, R6, R4 // b9296024 + KMCTR R2, R6, R4 // b92d6024 + // vector add and sub instructions VAB V3, V4, V4 // e743400000f3 VAH V3, V4, V4 // e743400010f3 |