From 43ea3054358a3d2dde5787e088dffaba27c4d91e Mon Sep 17 00:00:00 2001 From: Yao Zhang <lunaria21@gmail.com> Date: Thu, 10 Sep 2015 11:32:32 -0400 Subject: [PATCH] cmd/asm: added support for GOARCH=mips64{,le} Change-Id: I951387f88993715e86b6ab9f18d38ed5c691ee0f Reviewed-on: https://go-review.googlesource.com/14443 Reviewed-by: Minux Ma <minux@golang.org> --- src/cmd/asm/internal/arch/arch.go | 63 +++ src/cmd/asm/internal/arch/mips64.go | 64 +++ src/cmd/asm/internal/asm/asm.go | 18 + src/cmd/asm/internal/asm/endtoend_test.go | 4 + src/cmd/asm/internal/asm/operand_test.go | 88 +++++ src/cmd/asm/internal/asm/testdata/mips64.out | 99 +++++ src/cmd/asm/internal/asm/testdata/mips64.s | 392 +++++++++++++++++++ 7 files changed, 728 insertions(+) create mode 100644 src/cmd/asm/internal/arch/mips64.go create mode 100644 src/cmd/asm/internal/asm/testdata/mips64.out create mode 100644 src/cmd/asm/internal/asm/testdata/mips64.s diff --git a/src/cmd/asm/internal/arch/arch.go b/src/cmd/asm/internal/arch/arch.go index 04622e63ec..cc1aab6ad5 100644 --- a/src/cmd/asm/internal/arch/arch.go +++ b/src/cmd/asm/internal/arch/arch.go @@ -8,6 +8,7 @@ import ( "cmd/internal/obj" "cmd/internal/obj/arm" "cmd/internal/obj/arm64" + "cmd/internal/obj/mips" "cmd/internal/obj/ppc64" "cmd/internal/obj/x86" "fmt" @@ -65,6 +66,14 @@ func Set(GOARCH string) *Arch { return archArm() case "arm64": return archArm64() + case "mips64": + a := archMips64() + a.LinkArch = &mips.Linkmips64 + return a + case "mips64le": + a := archMips64() + a.LinkArch = &mips.Linkmips64le + return a case "ppc64": a := archPPC64() a.LinkArch = &ppc64.Linkppc64 @@ -363,3 +372,57 @@ func archPPC64() *Arch { IsJump: jumpPPC64, } } + +func archMips64() *Arch { + register := make(map[string]int16) + // Create maps for easy lookup of instruction names etc. + // Note that there is no list of names as there is for x86. + for i := mips.REG_R0; i <= mips.REG_R31; i++ { + register[obj.Rconv(i)] = int16(i) + } + for i := mips.REG_F0; i <= mips.REG_F31; i++ { + register[obj.Rconv(i)] = int16(i) + } + for i := mips.REG_M0; i <= mips.REG_M31; i++ { + register[obj.Rconv(i)] = int16(i) + } + for i := mips.REG_FCR0; i <= mips.REG_FCR31; i++ { + register[obj.Rconv(i)] = int16(i) + } + register["HI"] = mips.REG_HI + register["LO"] = mips.REG_LO + // Pseudo-registers. + register["SB"] = RSB + register["FP"] = RFP + register["PC"] = RPC + // Avoid unintentionally clobbering g using R30. + delete(register, "R30") + register["g"] = mips.REG_R30 + registerPrefix := map[string]bool{ + "F": true, + "FCR": true, + "M": true, + "R": true, + } + + instructions := make(map[string]int) + for i, s := range obj.Anames { + instructions[s] = i + } + for i, s := range mips.Anames { + if i >= obj.A_ARCHSPECIFIC { + instructions[s] = i + obj.ABaseMIPS64 + } + } + // Annoying alias. + instructions["JAL"] = mips.AJAL + + return &Arch{ + LinkArch: &mips.Linkmips64, + Instructions: instructions, + Register: register, + RegisterPrefix: registerPrefix, + RegisterNumber: mipsRegisterNumber, + IsJump: jumpMIPS64, + } +} diff --git a/src/cmd/asm/internal/arch/mips64.go b/src/cmd/asm/internal/arch/mips64.go new file mode 100644 index 0000000000..b5867d93df --- /dev/null +++ b/src/cmd/asm/internal/arch/mips64.go @@ -0,0 +1,64 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file encapsulates some of the odd characteristics of the +// 64-bit MIPS (MIPS64) instruction set, to minimize its interaction +// with the core of the assembler. + +package arch + +import "cmd/internal/obj/mips" + +func jumpMIPS64(word string) bool { + switch word { + case "BEQ", "BFPF", "BFPT", "BGEZ", "BGEZAL", "BGTZ", "BLEZ", "BLTZ", "BLTZAL", "BNE", "JMP", "JAL", "CALL": + return true + } + return false +} + +// IsMIPS64CMP reports whether the op (as defined by an mips.A* constant) is +// one of the CMP instructions that require special handling. +func IsMIPS64CMP(op int) bool { + switch op { + case mips.ACMPEQF, mips.ACMPEQD, mips.ACMPGEF, mips.ACMPGED, + mips.ACMPGTF, mips.ACMPGTD: + return true + } + return false +} + +// IsMIPS64MUL reports whether the op (as defined by an mips.A* constant) is +// one of the MUL/DIV/REM instructions that require special handling. +func IsMIPS64MUL(op int) bool { + switch op { + case mips.AMUL, mips.AMULU, mips.AMULV, mips.AMULVU, + mips.ADIV, mips.ADIVU, mips.ADIVV, mips.ADIVVU, + mips.AREM, mips.AREMU, mips.AREMV, mips.AREMVU: + return true + } + return false +} + +func mipsRegisterNumber(name string, n int16) (int16, bool) { + switch name { + case "F": + if 0 <= n && n <= 31 { + return mips.REG_F0 + n, true + } + case "FCR": + if 0 <= n && n <= 31 { + return mips.REG_FCR0 + n, true + } + case "M": + if 0 <= n && n <= 31 { + return mips.REG_M0 + n, true + } + case "R": + if 0 <= n && n <= 31 { + return mips.REG_R0 + n, true + } + } + return 0, false +} diff --git a/src/cmd/asm/internal/asm/asm.go b/src/cmd/asm/internal/asm/asm.go index 6128ca81e0..9da3664db1 100644 --- a/src/cmd/asm/internal/asm/asm.go +++ b/src/cmd/asm/internal/asm/asm.go @@ -373,6 +373,14 @@ func (p *Parser) asmJump(op int, cond string, a []obj.Addr) { prog.Reg = reg break } + if p.arch.Thechar == '0' { + // 3-operand jumps. + // First two must be registers + target = &a[2] + prog.From = a[0] + prog.Reg = p.getRegister(prog, op, &a[1]) + break + } fallthrough default: p.errorf("wrong number of arguments to %s instruction", obj.Aconv(op)) @@ -509,11 +517,21 @@ func (p *Parser) asmInstruction(op int, cond string, a []obj.Addr) { prog.From = a[0] prog.Reg = p.getRegister(prog, op, &a[1]) break + } else if p.arch.Thechar == '0' { + if arch.IsMIPS64CMP(op) || arch.IsMIPS64MUL(op) { + prog.From = a[0] + prog.Reg = p.getRegister(prog, op, &a[1]) + break + } } prog.From = a[0] prog.To = a[1] case 3: switch p.arch.Thechar { + case '0': + prog.From = a[0] + prog.Reg = p.getRegister(prog, op, &a[1]) + prog.To = a[2] case '5': // Special cases. if arch.IsARMSTREX(op) { diff --git a/src/cmd/asm/internal/asm/endtoend_test.go b/src/cmd/asm/internal/asm/endtoend_test.go index abe4e4efbc..6e339ad0b5 100644 --- a/src/cmd/asm/internal/asm/endtoend_test.go +++ b/src/cmd/asm/internal/asm/endtoend_test.go @@ -89,3 +89,7 @@ func TestAMD64EndToEnd(t *testing.T) { func Test386EndToEnd(t *testing.T) { testEndToEnd(t, "386") } + +func TestMIPS64EndToEnd(t *testing.T) { + testEndToEnd(t, "mips64") +} diff --git a/src/cmd/asm/internal/asm/operand_test.go b/src/cmd/asm/internal/asm/operand_test.go index 0f8271b5f8..ecf52c5620 100644 --- a/src/cmd/asm/internal/asm/operand_test.go +++ b/src/cmd/asm/internal/asm/operand_test.go @@ -65,6 +65,11 @@ func TestPPC64OperandParser(t *testing.T) { testOperandParser(t, parser, ppc64OperandTests) } +func TestMIPS64OperandParser(t *testing.T) { + parser := newParser("mips64") + testOperandParser(t, parser, mips64OperandTests) +} + type operandTest struct { input, output string } @@ -435,3 +440,86 @@ var arm64OperandTests = []operandTest{ {"(R29, RSP)", "(R29, RSP)"}, {"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms. } + +var mips64OperandTests = []operandTest{ + {"$((1<<63)-1)", "$9223372036854775807"}, + {"$(-64*1024)", "$-65536"}, + {"$(1024 * 8)", "$8192"}, + {"$-1", "$-1"}, + {"$-24(R4)", "$-24(R4)"}, + {"$0", "$0"}, + {"$0(R1)", "$(R1)"}, + {"$0.5", "$(0.5)"}, + {"$0x7000", "$28672"}, + {"$0x88888eef", "$2290650863"}, + {"$1", "$1"}, + {"$_main<>(SB)", "$_main<>(SB)"}, + {"$argframe(FP)", "$argframe(FP)"}, + {"$~3", "$-4"}, + {"(-288-3*8)(R1)", "-312(R1)"}, + {"(16)(R7)", "16(R7)"}, + {"(8)(g)", "8(g)"}, + {"(R0)", "(R0)"}, + {"(R3)", "(R3)"}, + {"(R4)", "(R4)"}, + {"(R5)", "(R5)"}, + {"-1(R4)", "-1(R4)"}, + {"-1(R5)", "-1(R5)"}, + {"6(PC)", "6(PC)"}, + {"F14", "F14"}, + {"F15", "F15"}, + {"F16", "F16"}, + {"F17", "F17"}, + {"F18", "F18"}, + {"F19", "F19"}, + {"F20", "F20"}, + {"F21", "F21"}, + {"F22", "F22"}, + {"F23", "F23"}, + {"F24", "F24"}, + {"F25", "F25"}, + {"F26", "F26"}, + {"F27", "F27"}, + {"F28", "F28"}, + {"F29", "F29"}, + {"F30", "F30"}, + {"F31", "F31"}, + {"R0", "R0"}, + {"R1", "R1"}, + {"R11", "R11"}, + {"R12", "R12"}, + {"R13", "R13"}, + {"R14", "R14"}, + {"R15", "R15"}, + {"R16", "R16"}, + {"R17", "R17"}, + {"R18", "R18"}, + {"R19", "R19"}, + {"R2", "R2"}, + {"R20", "R20"}, + {"R21", "R21"}, + {"R22", "R22"}, + {"R23", "R23"}, + {"R24", "R24"}, + {"R25", "R25"}, + {"R26", "R26"}, + {"R27", "R27"}, + {"R28", "R28"}, + {"R29", "R29"}, + {"R3", "R3"}, + {"R31", "R31"}, + {"R4", "R4"}, + {"R5", "R5"}, + {"R6", "R6"}, + {"R7", "R7"}, + {"R8", "R8"}, + {"R9", "R9"}, + {"LO", "LO"}, + {"a(FP)", "a(FP)"}, + {"g", "g"}, + {"ret+8(FP)", "ret+8(FP)"}, + {"runtime路abort(SB)", "runtime.abort(SB)"}, + {"路AddUint32(SB)", "\"\".AddUint32(SB)"}, + {"路trunc(SB)", "\"\".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/testdata/mips64.out b/src/cmd/asm/internal/asm/testdata/mips64.out new file mode 100644 index 0000000000..9263a7ba4b --- /dev/null +++ b/src/cmd/asm/internal/asm/testdata/mips64.out @@ -0,0 +1,99 @@ +8 00001 (testdata/mips64.s:8) TEXT foo(SB), 0, $0 +18 00002 (testdata/mips64.s:18) MOVW R1, R2 +19 00003 (testdata/mips64.s:19) MOVW LO, R1 +20 00004 (testdata/mips64.s:20) MOVW HI, R1 +21 00005 (testdata/mips64.s:21) MOVW R1, LO +22 00006 (testdata/mips64.s:22) MOVW R1, HI +23 00007 (testdata/mips64.s:23) MOVV R1, R2 +24 00008 (testdata/mips64.s:24) MOVV LO, R1 +25 00009 (testdata/mips64.s:25) MOVV HI, R1 +26 00010 (testdata/mips64.s:26) MOVV R1, LO +27 00011 (testdata/mips64.s:27) MOVV R1, HI +33 00012 (testdata/mips64.s:33) MOVW foo<>+3(SB), R2 +34 00013 (testdata/mips64.s:34) MOVW 16(R1), R2 +35 00014 (testdata/mips64.s:35) MOVW (R1), R2 +36 00015 (testdata/mips64.s:36) MOVV foo<>+3(SB), R2 +37 00016 (testdata/mips64.s:37) MOVV 16(R1), R2 +38 00017 (testdata/mips64.s:38) MOVV (R1), R2 +44 00018 (testdata/mips64.s:44) MOVB R1, R2 +50 00019 (testdata/mips64.s:50) MOVB foo<>+3(SB), R2 +51 00020 (testdata/mips64.s:51) MOVB 16(R1), R2 +52 00021 (testdata/mips64.s:52) MOVB (R1), R2 +61 00022 (testdata/mips64.s:61) MOVD foo<>+3(SB), F2 +62 00023 (testdata/mips64.s:62) MOVD 16(R1), F2 +63 00024 (testdata/mips64.s:63) MOVD (R1), F2 +69 00025 (testdata/mips64.s:69) MOVD $(0.10000000000000001), F2 +75 00026 (testdata/mips64.s:75) MOVD F1, F2 +81 00027 (testdata/mips64.s:81) MOVD F2, foo<>+3(SB) +82 00028 (testdata/mips64.s:82) MOVD F2, 16(R1) +83 00029 (testdata/mips64.s:83) MOVD F2, (R1) +92 00030 (testdata/mips64.s:92) MOVW R1, foo<>+3(SB) +93 00031 (testdata/mips64.s:93) MOVW R1, 16(R2) +94 00032 (testdata/mips64.s:94) MOVW R1, (R2) +95 00033 (testdata/mips64.s:95) MOVV R1, foo<>+3(SB) +96 00034 (testdata/mips64.s:96) MOVV R1, 16(R2) +97 00035 (testdata/mips64.s:97) MOVV R1, (R2) +103 00036 (testdata/mips64.s:103) MOVB R1, foo<>+3(SB) +104 00037 (testdata/mips64.s:104) MOVB R1, 16(R2) +105 00038 (testdata/mips64.s:105) MOVB R1, (R2) +114 00039 (testdata/mips64.s:114) MOVD F1, foo<>+3(SB) +115 00040 (testdata/mips64.s:115) MOVD F1, 16(R2) +116 00041 (testdata/mips64.s:116) MOVD F1, (R2) +125 00042 (testdata/mips64.s:125) MOVW FCR0, R1 +131 00043 (testdata/mips64.s:131) MOVW R1, FCR0 +137 00044 (testdata/mips64.s:137) MOVW R1, M1 +138 00045 (testdata/mips64.s:138) MOVV R1, M1 +144 00046 (testdata/mips64.s:144) MOVW M1, R1 +145 00047 (testdata/mips64.s:145) MOVV M1, R1 +158 00048 (testdata/mips64.s:158) ADD R1, R2, R3 +164 00049 (testdata/mips64.s:164) ADD $1, R2, R3 +170 00050 (testdata/mips64.s:170) ADD R1, R2 +176 00051 (testdata/mips64.s:176) ADD $4, R1 +182 00052 (testdata/mips64.s:182) MUL R1, R2 +188 00053 (testdata/mips64.s:188) SLL R1, R2, R3 +194 00054 (testdata/mips64.s:194) SLL R1, R2 +200 00055 (testdata/mips64.s:200) SLL $4, R1, R2 +206 00056 (testdata/mips64.s:206) SLL $4, R1 +215 00057 (testdata/mips64.s:215) MOVW $1, R1 +216 00058 (testdata/mips64.s:216) MOVV $1, R1 +222 00059 (testdata/mips64.s:222) MOVW $1, R1 +223 00060 (testdata/mips64.s:223) MOVW $foo(SB), R1 +224 00061 (testdata/mips64.s:224) MOVV $1, R1 +225 00062 (testdata/mips64.s:225) MOVV $foo(SB), R1 +236 00063 (testdata/mips64.s:236) JMP 64(PC) +237 00064 (testdata/mips64.s:237) JMP 63 +238 00065 (testdata/mips64.s:238) CALL 66(PC) +239 00066 (testdata/mips64.s:239) CALL 63 +245 00067 (testdata/mips64.s:245) JMP 4(R1) +246 00068 (testdata/mips64.s:246) JMP foo(SB) +247 00069 (testdata/mips64.s:247) CALL 4(R1) +248 00070 (testdata/mips64.s:248) CALL foo(SB) +258 00071 (testdata/mips64.s:258) BEQ R1, 72(PC) +259 00072 (testdata/mips64.s:259) BEQ R1, 71 +266 00073 (testdata/mips64.s:266) BEQ R1, R2, 74(PC) +267 00074 (testdata/mips64.s:267) BEQ R1, R2, 73 +277 00075 (testdata/mips64.s:277) BLTZ R1, 76(PC) +278 00076 (testdata/mips64.s:278) BLTZ R1, 75 +285 00077 (testdata/mips64.s:285) BFPT 78(PC) +286 00078 (testdata/mips64.s:286) BFPT 77 +296 00079 (testdata/mips64.s:296) ABSD F1, F2 +302 00080 (testdata/mips64.s:302) ADDD F1, F2 +308 00081 (testdata/mips64.s:308) ADDD F1, F2, F3 +314 00082 (testdata/mips64.s:314) CMPEQD F1, F2 +320 00083 (testdata/mips64.s:320) WORD $1 +321 00084 (testdata/mips64.s:321) WORD $foo(SB) +330 00085 (testdata/mips64.s:330) NOP +336 00086 (testdata/mips64.s:336) NOP R2 +342 00087 (testdata/mips64.s:342) NOP F2 +348 00088 (testdata/mips64.s:348) NOP R2 +354 00089 (testdata/mips64.s:354) NOP F2 +360 00090 (testdata/mips64.s:360) NOP $4 +365 00091 (testdata/mips64.s:365) SYSCALL +366 00092 (testdata/mips64.s:366) BREAK +367 00093 (testdata/mips64.s:367) BREAK $1, (R1) +376 00094 (testdata/mips64.s:376) SYSCALL +377 00095 (testdata/mips64.s:377) RET +382 00096 (testdata/mips64.s:382) CALL foo(SB) +383 00097 (testdata/mips64.s:383) JMP foo(SB) +384 00098 (testdata/mips64.s:384) CALL foo(SB) +392 00099 (testdata/mips64.s:392) END diff --git a/src/cmd/asm/internal/asm/testdata/mips64.s b/src/cmd/asm/internal/asm/testdata/mips64.s new file mode 100644 index 0000000000..4112b4b120 --- /dev/null +++ b/src/cmd/asm/internal/asm/testdata/mips64.s @@ -0,0 +1,392 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This input was created by taking the ppc64 testcase and modified +// by hand. + +TEXT foo(SB),0,$0 + +//inst: +// +// load ints and bytes +// +// LMOVW rreg ',' rreg +// { +// outcode(int($1), &$2, 0, &$4); +// } + MOVW R1, R2 + MOVW LO, R1 + MOVW HI, R1 + MOVW R1, LO + MOVW R1, HI + MOVV R1, R2 + MOVV LO, R1 + MOVV HI, R1 + MOVV R1, LO + MOVV R1, HI + +// LMOVW addr ',' rreg +// { +// outcode(int($1), &$2, 0, &$4); +// } + MOVW foo<>+3(SB), R2 + MOVW 16(R1), R2 + MOVW (R1), R2 + MOVV foo<>+3(SB), R2 + MOVV 16(R1), R2 + MOVV (R1), R2 + +// LMOVB rreg ',' rreg +// { +// outcode(int($1), &$2, 0, &$4); +// } + MOVB R1, R2 + +// LMOVB addr ',' rreg +// { +// outcode(int($1), &$2, 0, &$4); +// } + MOVB foo<>+3(SB), R2 + MOVB 16(R1), R2 + MOVB (R1), R2 + +// +// load floats +// +// LFMOV addr ',' freg +// { +// outcode(int($1), &$2, 0, &$4); +// } + MOVD foo<>+3(SB), F2 + MOVD 16(R1), F2 + MOVD (R1), F2 + +// LFMOV fimm ',' freg +// { +// outcode(int($1), &$2, 0, &$4); +// } + MOVD $0.1, F2 + +// LFMOV freg ',' freg +// { +// outcode(int($1), &$2, 0, &$4); +// } + MOVD F1, F2 + +// LFMOV freg ',' addr +// { +// outcode(int($1), &$2, 0, &$4); +// } + MOVD F2, foo<>+3(SB) + MOVD F2, 16(R1) + MOVD F2, (R1) + +// +// store ints and bytes +// +// LMOVW rreg ',' addr +// { +// outcode(int($1), &$2, 0, &$4); +// } + MOVW R1, foo<>+3(SB) + MOVW R1, 16(R2) + MOVW R1, (R2) + MOVV R1, foo<>+3(SB) + MOVV R1, 16(R2) + MOVV R1, (R2) + +// LMOVB rreg ',' addr +// { +// outcode(int($1), &$2, 0, &$4); +// } + MOVB R1, foo<>+3(SB) + MOVB R1, 16(R2) + MOVB R1, (R2) + +// +// store floats +// +// LMOVW freg ',' addr +// { +// outcode(int($1), &$2, 0, &$4); +// } + MOVD F1, foo<>+3(SB) + MOVD F1, 16(R2) + MOVD F1, (R2) + +// +// floating point status +// +// LMOVW fpscr ',' freg +// { +// outcode(int($1), &$2, 0, &$4); +// } + MOVW FCR0, R1 + +// LMOVW freg ',' fpscr +// { +// outcode(int($1), &$2, 0, &$4); +// } + MOVW R1, FCR0 + +// LMOVW rreg ',' mreg +// { +// outcode(int($1), &$2, 0, &$4); +// } + MOVW R1, M1 + MOVV R1, M1 + +// LMOVW mreg ',' rreg +// { +// outcode(int($1), &$2, 0, &$4); +// } + MOVW M1, R1 + MOVV M1, R1 + + +// +// integer operations +// logical instructions +// shift instructions +// unary instructions +// +// LADDW rreg ',' sreg ',' rreg +// { +// outcode(int($1), &$2, int($4), &$6); +// } + ADD R1, R2, R3 + +// LADDW imm ',' sreg ',' rreg +// { +// outcode(int($1), &$2, int($4), &$6); +// } + ADD $1, R2, R3 + +// LADDW rreg ',' rreg +// { +// outcode(int($1), &$2, 0, &$4); +// } + ADD R1, R2 + +// LADDW imm ',' rreg +// { +// outcode(int($1), &$2, 0, &$4); +// } + ADD $4, R1 + +// LMUL rreg ',' rreg +// { +// outcode(int($1), &$2, 0, &$4); +// } + MUL R1, R2 + +// LSHW rreg ',' sreg ',' rreg +// { +// outcode(int($1), &$2, int($4), &$6); +// } + SLL R1, R2, R3 + +// LSHW rreg ',' rreg +// { +// outcode(int($1), &$2, 0, &$4); +// } + SLL R1, R2 + +// LSHW imm ',' sreg ',' rreg +// { +// outcode(int($1), &$2, int($4), &$6); +// } + SLL $4, R1, R2 + +// LSHW imm ',' rreg +// { +// outcode(int($1), &$2, 0, &$4); +// } + SLL $4, R1 + +// +// move immediate: macro for lui+or, addi, addis, and other combinations +// +// LMOVW imm ',' rreg +// { +// outcode(int($1), &$2, 0, &$4); +// } + MOVW $1, R1 + MOVV $1, R1 + +// LMOVW ximm ',' rreg +// { +// outcode(int($1), &$2, 0, &$4); +// } + MOVW $1, R1 + MOVW $foo(SB), R1 + MOVV $1, R1 + MOVV $foo(SB), R1 + + +// +// branch +// +// LBRA rel +// { +// outcode(int($1), &nullgen, 0, &$2); +// } +label0: + JMP 1(PC) + JMP label0+0 + JAL 1(PC) + JAL label0+0 + +// LBRA addr +// { +// outcode(int($1), &nullgen, 0, &$2); +// } + JMP 4(R1) + JMP foo+0(SB) + JAL 4(R1) + JAL foo+0(SB) + +// +// BEQ/BNE +// +// LBRA rreg ',' rel +// { +// outcode(int($1), &$2, 0, &$4); +// } +label1: + BEQ R1, 1(PC) + BEQ R1, label1 + +// LBRA rreg ',' sreg ',' rel +// { +// outcode(int($1), &$2, 0, &$4); +// } +label2: + BEQ R1, R2, 1(PC) + BEQ R1, R2, label2 + +// +// other integer conditional branch +// +// LBRA rreg ',' rel +// { +// outcode(int($1), &$2, 0, &$4); +// } +label3: + BLTZ R1, 1(PC) + BLTZ R1, label3 + +// +// floating point conditional branch +// +// LBRA rel +label4: + BFPT 1(PC) + BFPT label4 + + +// +// floating point operate +// +// LFCONV freg ',' freg +// { +// outcode(int($1), &$2, 0, &$4); +// } + ABSD F1, F2 + +// LFADD freg ',' freg +// { +// outcode(int($1), &$2, 0, &$4); +// } + ADDD F1, F2 + +// LFADD freg ',' freg ',' freg +// { +// outcode(int($1), &$2, int($4.Reg), &$6); +// } + ADDD F1, F2, F3 + +// LFCMP freg ',' freg +// { +// outcode(int($1), &$2, 0, &$4); +// } + CMPEQD F1, F2 + + +// +// WORD +// + WORD $1 + WORD $foo(SB) + +// +// NOP +// +// LNOP comma // asm doesn't support the trailing comma. +// { +// outcode(int($1), &nullgen, 0, &nullgen); +// } + NOP + +// LNOP rreg comma // asm doesn't support the trailing comma. +// { +// outcode(int($1), &$2, 0, &nullgen); +// } + NOP R2 + +// LNOP freg comma // asm doesn't support the trailing comma. +// { +// outcode(int($1), &$2, 0, &nullgen); +// } + NOP F2 + +// LNOP ',' rreg // asm doesn't support the leading comma. +// { +// outcode(int($1), &nullgen, 0, &$3); +// } + NOP R2 + +// LNOP ',' freg // asm doesn't support the leading comma. +// { +// outcode(int($1), &nullgen, 0, &$3); +// } + NOP F2 + +// LNOP imm +// { +// outcode(int($1), &$2, 0, &nullgen); +// } + NOP $4 + +// +// special +// + SYSCALL + BREAK + BREAK $1, (R1) // overloaded CACHE opcode + +// +// RET +// +// LRETRN comma // asm doesn't support the trailing comma. +// { +// outcode(int($1), &nullgen, 0, &nullgen); +// } + SYSCALL + RET + + +// More JMP/JAL cases, and canonical names JMP, CALL. + + JAL foo(SB) + JMP foo(SB) + CALL foo(SB) + +// END +// +// LEND comma // asm doesn't support the trailing comma. +// { +// outcode(int($1), &nullgen, 0, &nullgen); +// } + END -- 2.30.9