diff --git a/src/cmd/asm/internal/asm/asm.go b/src/cmd/asm/internal/asm/asm.go index bd9ba91b22..5cbf2232d1 100644 --- a/src/cmd/asm/internal/asm/asm.go +++ b/src/cmd/asm/internal/asm/asm.go @@ -460,17 +460,6 @@ func (p *Parser) asmInstruction(op int, cond string, a []obj.Addr) { prog.From = a[0] prog.To = a[1] switch p.arch.Thechar { - case '6', '8': - // DX:AX as a register pair can only appear on the RHS. - // Bizarrely, to obj it's specified by setting index on the LHS. - // TODO: can we fix this? - if a[1].Reg2 != 0 { - if a[0].Reg2 != 0 { - p.errorf("register pair must be on LHS") - } - prog.From.Index = int16(a[1].Reg2) - prog.To.Reg2 = 0 - } case '9': var reg0, reg1 int16 // Handle (R1+R2) @@ -488,7 +477,7 @@ func (p *Parser) asmInstruction(op int, cond string, a []obj.Addr) { case 3: switch p.arch.Thechar { case '5': - // Strange special case. + // Special cases. if arch.IsARMSTREX(op) { /* STREX x, (y), z @@ -504,20 +493,9 @@ func (p *Parser) asmInstruction(op int, cond string, a []obj.Addr) { prog.Reg = p.getRegister(prog, op, &a[1]) prog.To = a[2] case '6', '8': - // CMPSD etc.; third operand is imm8, stored in offset, or a register. prog.From = a[0] - prog.To = a[1] - switch a[2].Type { - case obj.TYPE_MEM: - prog.To.Offset = p.getConstant(prog, op, &a[2]) - case obj.TYPE_REG: - // Strange reordering. - prog.To = a[2] - prog.From = a[1] - prog.To.Offset = p.getImmediate(prog, op, &a[0]) - default: - p.errorf("expected offset or register for 3rd operand") - } + prog.From3 = a[1] + prog.To = a[2] case '9': if arch.IsPPC64CMP(op) { // CMPW etc.; third argument is a CR register that goes into prog.Reg. diff --git a/src/cmd/asm/internal/asm/endtoend_test.go b/src/cmd/asm/internal/asm/endtoend_test.go index 011a86cc36..7b4bdfccd0 100644 --- a/src/cmd/asm/internal/asm/endtoend_test.go +++ b/src/cmd/asm/internal/asm/endtoend_test.go @@ -79,11 +79,9 @@ func TestARMEndToEnd(t *testing.T) { } func TestAMD64EndToEnd(t *testing.T) { - t.Skip("broken") testEndToEnd(t, "amd64") } func Test386EndToEnd(t *testing.T) { - t.Skip("broken") testEndToEnd(t, "386") } diff --git a/src/cmd/asm/internal/asm/operand_test.go b/src/cmd/asm/internal/asm/operand_test.go index 5190ed45eb..179d63db26 100644 --- a/src/cmd/asm/internal/asm/operand_test.go +++ b/src/cmd/asm/internal/asm/operand_test.go @@ -41,47 +41,14 @@ func testOperandParser(t *testing.T, parser *Parser, tests []operandTest) { } } -func testX86RegisterPair(t *testing.T, parser *Parser) { - // Special case for AX:DX, which is really two operands so isn't printed correcctly - // by Aconv, but is OK by the -S output. - parser.start(lex.Tokenize("AX:BX)")) - addr := obj.Addr{} - parser.operand(&addr) - want := obj.Addr{ - Type: obj.TYPE_REG, - Reg: parser.arch.Register["AX"], - Reg2: parser.arch.Register["BX"], // TODO: clean up how this is encoded in parse.go - } - if want != addr { - t.Errorf("AX:DX: expected %+v got %+v", want, addr) - } - // Special case for foo(SB):DX, which is really two operands so isn't printed correctly - // by Aconv, but is OK by the -S output. - parser.start(lex.Tokenize("foo+4(SB):AX")) - addr = obj.Addr{} - parser.operand(&addr) - want = obj.Addr{ - Type: obj.TYPE_MEM, - Name: obj.NAME_EXTERN, - Offset: 4, - Sym: obj.Linklookup(parser.ctxt, "foo", 0), - Reg2: parser.arch.Register["AX"], // TODO: clean up how this is encoded in parse.go - } - if want != addr { - t.Errorf("foo+4(SB):AX: expected %+v got %+v", want, addr) - } -} - func TestAMD64OperandParser(t *testing.T) { parser := newParser("amd64") testOperandParser(t, parser, amd64OperandTests) - testX86RegisterPair(t, parser) } func Test386OperandParser(t *testing.T) { parser := newParser("386") testOperandParser(t, parser, x86OperandTests) - testX86RegisterPair(t, parser) } func TestARMOperandParser(t *testing.T) { @@ -113,7 +80,6 @@ type operandTest struct { // Examples collected by scanning all the assembly in the standard repo. var amd64OperandTests = []operandTest{ - // {"AX:DX", "AX:DX"}, Handled in TestAMD64OperandParser directly. {"$(-1.0)", "$(-1.0)"}, {"$(0.0)", "$(0.0)"}, {"$(0x2000000+116)", "$33554548"}, diff --git a/src/cmd/asm/internal/asm/parse.go b/src/cmd/asm/internal/asm/parse.go index 27d311293f..f37c5a0168 100644 --- a/src/cmd/asm/internal/asm/parse.go +++ b/src/cmd/asm/internal/asm/parse.go @@ -109,6 +109,7 @@ func (p *Parser) line() bool { operands := make([][]lex.Token, 0, 3) // Zero or more comma-separated operands, one per loop. nesting := 0 + colon := -1 for tok != '\n' && tok != ';' { // Process one operand. items := make([]lex.Token, 0, 3) @@ -135,7 +136,16 @@ func (p *Parser) line() bool { p.errorf("unexpected EOF") return false } - if tok == '\n' || tok == ';' || (nesting == 0 && tok == ',') { + // Split operands on comma. Also, the old syntax on x86 for a "register pair" + // was AX:DX, for which the new syntax is DX, AX. Note the reordering. + if tok == '\n' || tok == ';' || (nesting == 0 && (tok == ',' || tok == ':')) { + if tok == ':' { + // Remember this location so we can swap the operands below. + if colon >= 0 { + p.errorf("invalid ':' in operand") + } + colon = len(operands) + } break } if tok == '(' || tok == '[' { @@ -148,8 +158,13 @@ func (p *Parser) line() bool { } if len(items) > 0 { operands = append(operands, items) - } else if len(operands) > 0 || tok == ',' { - // Had a comma with nothing after. + if colon >= 0 && len(operands) == colon+2 { + // AX:DX becomes DX, AX. + operands[colon], operands[colon+1] = operands[colon+1], operands[colon] + colon = -1 + } + } else if len(operands) > 0 || tok == ',' || colon >= 0 { + // Had a separator with nothing after. p.errorf("missing operand") } } @@ -226,7 +241,7 @@ func (p *Parser) parseScale(s string) int8 { // operand parses a general operand and stores the result in *a. func (p *Parser) operand(a *obj.Addr) bool { - // fmt.Printf("Operand: %v\n", p.input) + //fmt.Printf("Operand: %v\n", p.input) if len(p.input) == 0 { p.errorf("empty operand: cannot happen") return false @@ -297,6 +312,8 @@ func (p *Parser) operand(a *obj.Addr) bool { if r2 != 0 { // Form is R1:R2. It is on RHS and the second register // needs to go into the LHS. This is a horrible hack. TODO. + // TODO: If we never see this again, can delete Addr.Reg2. + panic("cannot happen") a.Reg2 = r2 } } @@ -362,18 +379,8 @@ func (p *Parser) operand(a *obj.Addr) bool { // fmt.Printf("offset %d \n", a.Offset) } - // Odd x86 case: sym+4(SB):AX. Have name, colon, register. - if p.peek() == ':' && a.Name != obj.NAME_NONE && a.Reg2 == 0 && (p.arch.Thechar == '6' || p.arch.Thechar == '8') { - p.get(':') - r2, ok := p.registerReference(p.next().String()) - if !ok { - return false - } - a.Reg2 = r2 // TODO: See comment about Reg3 above. - } else { - // Register indirection: (reg) or (index*scale). We are on the opening paren. - p.registerIndirect(a, prefix) - } + // Register indirection: (reg) or (index*scale). We are on the opening paren. + p.registerIndirect(a, prefix) // fmt.Printf("DONE %s\n", p.arch.Dconv(&emptyProg, 0, a)) p.expect(scanner.EOF) @@ -449,15 +456,10 @@ func (p *Parser) register(name string, prefix rune) (r1, r2 int16, scale int8, o } c := p.peek() if c == ':' || c == ',' || c == '+' { - // 2nd register; syntax (R1:R2) etc. No two architectures agree. + // 2nd register; syntax (R1+R2) etc. No two architectures agree. // Check the architectures match the syntax. char := p.arch.Thechar switch p.next().ScanToken { - case ':': - if char != '6' && char != '8' { - p.errorf("illegal register pair syntax") - return - } case ',': if char != '5' { p.errorf("illegal register pair syntax") diff --git a/src/cmd/asm/internal/asm/testdata/386.out b/src/cmd/asm/internal/asm/testdata/386.out index 8ac94db82b..d88277d1ae 100644 --- a/src/cmd/asm/internal/asm/testdata/386.out +++ b/src/cmd/asm/internal/asm/testdata/386.out @@ -1,49 +1,49 @@ -5 00001 (testdata/386.s:5) TEXT foo(SB),$0 -8 00002 (testdata/386.s:8) SETCC ,AX -9 00003 (testdata/386.s:9) SETCC ,foo+4(SB) -12 00004 (testdata/386.s:12) DIVB AX, -13 00005 (testdata/386.s:13) DIVB foo+4(SB), -14 00006 (testdata/386.s:14) PUSHL $foo+4(SB), -15 00007 (testdata/386.s:15) POPL ,AX -18 00008 (testdata/386.s:18) SUBB $1,AX -19 00009 (testdata/386.s:19) SUBB $1,foo+4(SB) -20 00010 (testdata/386.s:20) SUBB BX,AX -21 00011 (testdata/386.s:21) SUBB BX,foo+4(SB) -24 00012 (testdata/386.s:24) CMPB AX,$1 -25 00013 (testdata/386.s:25) CMPB foo+4(SB),$4 -26 00014 (testdata/386.s:26) CMPB BX,AX -27 00015 (testdata/386.s:27) CMPB foo+4(SB),BX -31 00016 (testdata/386.s:31) JCS , -32 00017 (testdata/386.s:32) JCS ,16(PC) -35 00018 (testdata/386.s:35) CALL ,AX -36 00019 (testdata/386.s:36) JMP ,AX -37 00020 (testdata/386.s:37) CALL ,*foo(SB) -38 00021 (testdata/386.s:38) JMP ,$4 -39 00022 (testdata/386.s:39) JMP ,16 -40 00023 (testdata/386.s:40) CALL ,foo(SB) -42 00024 (testdata/386.s:42) CALL ,foo+4(SB)(AX*4) -43 00025 (testdata/386.s:43) CALL ,4(SP) -44 00026 (testdata/386.s:44) CALL ,(AX) -45 00027 (testdata/386.s:45) CALL ,(SP) -47 00028 (testdata/386.s:47) CALL ,(AX)(AX*4) -48 00029 (testdata/386.s:48) CALL ,4(SP) -49 00030 (testdata/386.s:49) CALL ,(AX) -50 00031 (testdata/386.s:50) CALL ,(SP) -52 00032 (testdata/386.s:52) JMP ,(AX)(AX*4) -55 00033 (testdata/386.s:55) NOP , -56 00034 (testdata/386.s:56) NOP AX, -57 00035 (testdata/386.s:57) NOP foo+4(SB), -60 00036 (testdata/386.s:60) SHLL $4,BX -61 00037 (testdata/386.s:61) SHLL $4,foo+4(SB) -62 00038 (testdata/386.s:62) SHLL $4,foo+4(SB):AX -65 00039 (testdata/386.s:65) MOVL AX,BX -66 00040 (testdata/386.s:66) MOVL $4,BX -69 00041 (testdata/386.s:69) IMULL AX, -70 00042 (testdata/386.s:70) IMULL $4,CX -71 00043 (testdata/386.s:71) IMULL AX,BX -74 00044 (testdata/386.s:74) CMPPD X0,$4,X1 -75 00045 (testdata/386.s:75) CMPPD X0,foo+4(SB) -78 00046 (testdata/386.s:78) PINSRD (AX),$1,X0 -79 00047 (testdata/386.s:79) PINSRD foo+4(FP),$2,X0 -83 00048 (testdata/386.s:83) LOOP , -86 00049 (testdata/386.s:86) RET , +5 00001 (testdata/386.s:5) TEXT foo(SB), $0 +8 00002 (testdata/386.s:8) SETCC AX +9 00003 (testdata/386.s:9) SETCC foo+4(SB) +12 00004 (testdata/386.s:12) DIVB AX +13 00005 (testdata/386.s:13) DIVB foo+4(SB) +14 00006 (testdata/386.s:14) PUSHL $foo+4(SB) +15 00007 (testdata/386.s:15) POPL AX +18 00008 (testdata/386.s:18) SUBB $1, AX +19 00009 (testdata/386.s:19) SUBB $1, foo+4(SB) +20 00010 (testdata/386.s:20) SUBB BX, AX +21 00011 (testdata/386.s:21) SUBB BX, foo+4(SB) +24 00012 (testdata/386.s:24) CMPB AX, $1 +25 00013 (testdata/386.s:25) CMPB foo+4(SB), $4 +26 00014 (testdata/386.s:26) CMPB BX, AX +27 00015 (testdata/386.s:27) CMPB foo+4(SB), BX +31 00016 (testdata/386.s:31) JCS +32 00017 (testdata/386.s:32) JCS 16(PC) +35 00018 (testdata/386.s:35) CALL AX +36 00019 (testdata/386.s:36) JMP AX +37 00020 (testdata/386.s:37) CALL *foo(SB) +38 00021 (testdata/386.s:38) JMP $4 +39 00022 (testdata/386.s:39) JMP 16 +40 00023 (testdata/386.s:40) CALL foo(SB) +42 00024 (testdata/386.s:42) CALL foo+4(SB)(AX*4) +43 00025 (testdata/386.s:43) CALL 4(SP) +44 00026 (testdata/386.s:44) CALL (AX) +45 00027 (testdata/386.s:45) CALL (SP) +47 00028 (testdata/386.s:47) CALL (AX)(AX*4) +48 00029 (testdata/386.s:48) CALL 4(SP) +49 00030 (testdata/386.s:49) CALL (AX) +50 00031 (testdata/386.s:50) CALL (SP) +52 00032 (testdata/386.s:52) JMP (AX)(AX*4) +55 00033 (testdata/386.s:55) NOP +56 00034 (testdata/386.s:56) NOP AX +57 00035 (testdata/386.s:57) NOP foo+4(SB) +60 00036 (testdata/386.s:60) SHLL $4, BX +61 00037 (testdata/386.s:61) SHLL $4, foo+4(SB) +62 00038 (testdata/386.s:62) SHLL $4, AX, foo+4(SB) +65 00039 (testdata/386.s:65) MOVL AX, BX +66 00040 (testdata/386.s:66) MOVL $4, BX +69 00041 (testdata/386.s:69) IMULL AX +70 00042 (testdata/386.s:70) IMULL $4, CX +71 00043 (testdata/386.s:71) IMULL AX, BX +74 00044 (testdata/386.s:74) CMPPD X0, X1, 4 +75 00045 (testdata/386.s:75) CMPPD X0, foo+4(SB), 4 +78 00046 (testdata/386.s:78) PINSRD $1, (AX), X0 +79 00047 (testdata/386.s:79) PINSRD $2, foo+4(FP), X0 +83 00048 (testdata/386.s:83) LOOP +86 00049 (testdata/386.s:86) RET diff --git a/src/cmd/asm/internal/asm/testdata/amd64.out b/src/cmd/asm/internal/asm/testdata/amd64.out index e647a5c6bd..020a422976 100644 --- a/src/cmd/asm/internal/asm/testdata/amd64.out +++ b/src/cmd/asm/internal/asm/testdata/amd64.out @@ -1,57 +1,57 @@ -5 00001 (testdata/amd64.s:5) TEXT foo(SB),$0 -8 00002 (testdata/amd64.s:8) NEGQ ,R11 -9 00003 (testdata/amd64.s:9) NEGQ ,4(R11) -10 00004 (testdata/amd64.s:10) NEGQ ,foo+4(SB) -13 00005 (testdata/amd64.s:13) INT $4, -14 00006 (testdata/amd64.s:14) DIVB R11, -15 00007 (testdata/amd64.s:15) DIVB 4(R11), -16 00008 (testdata/amd64.s:16) DIVB foo+4(SB), -19 00009 (testdata/amd64.s:19) SUBQ $4,DI -20 00010 (testdata/amd64.s:20) SUBQ R11,DI -21 00011 (testdata/amd64.s:21) SUBQ 4(R11),DI -22 00012 (testdata/amd64.s:22) SUBQ foo+4(SB),DI -23 00013 (testdata/amd64.s:23) SUBQ $4,8(R12) -24 00014 (testdata/amd64.s:24) SUBQ R11,8(R12) -25 00015 (testdata/amd64.s:25) SUBQ R11,foo+4(SB) -28 00016 (testdata/amd64.s:28) CMPB CX,$4 -32 00017 (testdata/amd64.s:32) JCS ,13(PC) -33 00018 (testdata/amd64.s:33) JCS ,17 -36 00019 (testdata/amd64.s:36) JMP ,15(PC) -37 00020 (testdata/amd64.s:37) JMP ,17 -38 00021 (testdata/amd64.s:38) JMP ,foo+4(SB) -39 00022 (testdata/amd64.s:39) JMP ,bar<>+4(SB) -40 00023 (testdata/amd64.s:40) JMP ,bar<>+4(SB)(R11*4) -41 00024 (testdata/amd64.s:41) JMP ,4(SP) -42 00025 (testdata/amd64.s:42) JMP ,(R12) -44 00026 (testdata/amd64.s:44) JMP ,(R12)(R13*4) -45 00027 (testdata/amd64.s:45) JMP ,(AX) -46 00028 (testdata/amd64.s:46) JMP ,(SP) -48 00029 (testdata/amd64.s:48) JMP ,(AX)(AX*4) -49 00030 (testdata/amd64.s:49) JMP ,4(SP) -50 00031 (testdata/amd64.s:50) JMP ,(R12) -52 00032 (testdata/amd64.s:52) JMP ,(R12)(R13*4) -53 00033 (testdata/amd64.s:53) JMP ,(AX) -54 00034 (testdata/amd64.s:54) JMP ,(SP) -56 00035 (testdata/amd64.s:56) JMP ,(AX)(AX*4) -57 00036 (testdata/amd64.s:57) JMP ,R13 -60 00037 (testdata/amd64.s:60) NOP , -61 00038 (testdata/amd64.s:61) NOP AX, -62 00039 (testdata/amd64.s:62) NOP foo+4(SB), -65 00040 (testdata/amd64.s:65) SHLL R11,R12 -66 00041 (testdata/amd64.s:66) SHLL R11,foo+4(SB) -67 00042 (testdata/amd64.s:67) SHLL R11,R11:AX -70 00043 (testdata/amd64.s:70) MOVL AX,R11 -71 00044 (testdata/amd64.s:71) MOVL $4,R11 -72 00045 (testdata/amd64.s:72) MOVL AX,AX:CS -75 00046 (testdata/amd64.s:75) IMULB $4, -76 00047 (testdata/amd64.s:76) IMULB R11, -77 00048 (testdata/amd64.s:77) IMULB $4,R11 -78 00049 (testdata/amd64.s:78) IMULB R11,R12 -79 00050 (testdata/amd64.s:79) IMULB R11,foo+4(SB) -82 00051 (testdata/amd64.s:82) CMPPD R11,$4,R12 -83 00052 (testdata/amd64.s:83) CMPPD R11,foo+4(SB) -86 00053 (testdata/amd64.s:86) PINSRW R11,$4,AX -87 00054 (testdata/amd64.s:87) PINSRW foo+4(SB),$4,AX -90 00055 (testdata/amd64.s:90) RETFL $4, -94 00056 (testdata/amd64.s:94) LOOP , -97 00057 (testdata/amd64.s:97) RET , +5 00001 (testdata/amd64.s:5) TEXT foo(SB), $0 +8 00002 (testdata/amd64.s:8) NEGQ R11 +9 00003 (testdata/amd64.s:9) NEGQ 4(R11) +10 00004 (testdata/amd64.s:10) NEGQ foo+4(SB) +13 00005 (testdata/amd64.s:13) INT $4 +14 00006 (testdata/amd64.s:14) DIVB R11 +15 00007 (testdata/amd64.s:15) DIVB 4(R11) +16 00008 (testdata/amd64.s:16) DIVB foo+4(SB) +19 00009 (testdata/amd64.s:19) SUBQ $4, DI +20 00010 (testdata/amd64.s:20) SUBQ R11, DI +21 00011 (testdata/amd64.s:21) SUBQ 4(R11), DI +22 00012 (testdata/amd64.s:22) SUBQ foo+4(SB), DI +23 00013 (testdata/amd64.s:23) SUBQ $4, 8(R12) +24 00014 (testdata/amd64.s:24) SUBQ R11, 8(R12) +25 00015 (testdata/amd64.s:25) SUBQ R11, foo+4(SB) +28 00016 (testdata/amd64.s:28) CMPB CX, $4 +32 00017 (testdata/amd64.s:32) JCS 13(PC) +33 00018 (testdata/amd64.s:33) JCS 17 +36 00019 (testdata/amd64.s:36) JMP 15(PC) +37 00020 (testdata/amd64.s:37) JMP 17 +38 00021 (testdata/amd64.s:38) JMP foo+4(SB) +39 00022 (testdata/amd64.s:39) JMP bar<>+4(SB) +40 00023 (testdata/amd64.s:40) JMP bar<>+4(SB)(R11*4) +41 00024 (testdata/amd64.s:41) JMP 4(SP) +42 00025 (testdata/amd64.s:42) JMP (R12) +44 00026 (testdata/amd64.s:44) JMP (R12)(R13*4) +45 00027 (testdata/amd64.s:45) JMP (AX) +46 00028 (testdata/amd64.s:46) JMP (SP) +48 00029 (testdata/amd64.s:48) JMP (AX)(AX*4) +49 00030 (testdata/amd64.s:49) JMP 4(SP) +50 00031 (testdata/amd64.s:50) JMP (R12) +52 00032 (testdata/amd64.s:52) JMP (R12)(R13*4) +53 00033 (testdata/amd64.s:53) JMP (AX) +54 00034 (testdata/amd64.s:54) JMP (SP) +56 00035 (testdata/amd64.s:56) JMP (AX)(AX*4) +57 00036 (testdata/amd64.s:57) JMP R13 +60 00037 (testdata/amd64.s:60) NOP +61 00038 (testdata/amd64.s:61) NOP AX +62 00039 (testdata/amd64.s:62) NOP foo+4(SB) +65 00040 (testdata/amd64.s:65) SHLL R11, R12 +66 00041 (testdata/amd64.s:66) SHLL R11, foo+4(SB) +67 00042 (testdata/amd64.s:67) SHLL R11, AX, R11 +70 00043 (testdata/amd64.s:70) MOVL AX, R11 +71 00044 (testdata/amd64.s:71) MOVL $4, R11 +72 00045 (testdata/amd64.s:72) MOVL AX, CS, AX +75 00046 (testdata/amd64.s:75) IMULB $4 +76 00047 (testdata/amd64.s:76) IMULB R11 +77 00048 (testdata/amd64.s:77) IMULB $4, R11 +78 00049 (testdata/amd64.s:78) IMULB R11, R12 +79 00050 (testdata/amd64.s:79) IMULB R11, foo+4(SB) +82 00051 (testdata/amd64.s:82) CMPPD R11, R12, 4 +83 00052 (testdata/amd64.s:83) CMPPD R11, foo+4(SB), 4 +86 00053 (testdata/amd64.s:86) PINSRW $4, R11, AX +87 00054 (testdata/amd64.s:87) PINSRW $4, foo+4(SB), AX +90 00055 (testdata/amd64.s:90) RETFL $4 +94 00056 (testdata/amd64.s:94) LOOP +97 00057 (testdata/amd64.s:97) RET diff --git a/src/cmd/asm/internal/asm/testdata/amd64.s b/src/cmd/asm/internal/asm/testdata/amd64.s index eb13a1f96e..410057612b 100644 --- a/src/cmd/asm/internal/asm/testdata/amd64.s +++ b/src/cmd/asm/internal/asm/testdata/amd64.s @@ -64,7 +64,7 @@ label: // LTYPES spec5 { outcode($1, &$2); } SHLL R11, R12 SHLL R11, foo+4(SB) - SHLL R11, R11:AX + SHLL R11, R11:AX // Old syntax, still accepted. // LTYPEM spec6 { outcode($1, &$2); } MOVL AX, R11