Commit 5d28bc58 authored by Vladimir Stefanovic's avatar Vladimir Stefanovic Committed by Brad Fitzpatrick

cmd/internal/obj/mips: add support for GOARCH=mips{,le}

Implements subset of MIPS32(r1) instruction set.

Change-Id: Iba017350f6c2763de05d4d1bc2f123e8eb76d0ff
Reviewed-on: https://go-review.googlesource.com/31475
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: default avatarCherry Zhang <cherryyz@google.com>
parent c41137d2
......@@ -415,7 +415,7 @@ func archMips64() *Arch {
}
for i, s := range mips.Anames {
if obj.As(i) >= obj.A_ARCHSPECIFIC {
instructions[s] = obj.As(i) + obj.ABaseMIPS64
instructions[s] = obj.As(i) + obj.ABaseMIPS
}
}
// Annoying alias.
......
......@@ -311,7 +311,7 @@ const (
ABaseAMD64
ABasePPC64
ABaseARM64
ABaseMIPS64
ABaseMIPS
ABaseS390X
AllowedOpCodes = 1 << 10 // The number of opcodes available for any given architecture.
......@@ -532,7 +532,7 @@ const (
// R_ADDRARM64 relocates an adrp, add pair to compute the address of the
// referenced symbol.
R_ADDRARM64
// R_ADDRMIPS (only used on mips64) resolves to the low 16 bits of an external
// R_ADDRMIPS (only used on mips/mips64) resolves to the low 16 bits of an external
// address, by encoding it into the instruction.
R_ADDRMIPS
// R_ADDROFF resolves to a 32-bit offset from the beginning of the section
......@@ -660,7 +660,7 @@ const (
// TODO(mundaym): remove once variants can be serialized - see issue 14218.
R_PCRELDBL
// R_ADDRMIPSU (only used on mips64) resolves to the sign-adjusted "upper" 16
// R_ADDRMIPSU (only used on mips/mips64) resolves to the sign-adjusted "upper" 16
// bits (bit 16-31) of an external address, by encoding it into the instruction.
R_ADDRMIPSU
// R_ADDRMIPSTLS (only used on mips64) resolves to the low 16 bits of a TLS
......
......@@ -44,7 +44,7 @@ const (
)
const (
REG_R0 = obj.RBaseMIPS64 + iota
REG_R0 = obj.RBaseMIPS + iota
REG_R1
REG_R2
REG_R3
......@@ -217,6 +217,11 @@ const (
NSCHED = 20
)
const (
Mips32 = 32
Mips64 = 64
)
const (
C_NONE = iota
C_REG
......@@ -258,7 +263,7 @@ const (
)
const (
AABSD = obj.ABaseMIPS64 + obj.A_ARCHSPECIFIC + iota
AABSD = obj.ABaseMIPS + obj.A_ARCHSPECIFIC + iota
AABSF
AABSW
AADD
......@@ -278,6 +283,12 @@ const (
ABLTZAL
ABNE
ABREAK
ACLO
ACLZ
ACMOVF
ACMOVN
ACMOVT
ACMOVZ
ACMPEQD
ACMPEQF
ACMPGED
......@@ -290,6 +301,7 @@ const (
ADIVU
ADIVW
AGOK
ALL
ALUI
AMOVB
AMOVBU
......@@ -319,9 +331,12 @@ const (
AREM
AREMU
ARFE
ASC
ASGT
ASGTU
ASLL
ASQRTD
ASQRTF
ASRA
ASRL
ASUB
......@@ -329,11 +344,14 @@ const (
ASUBF
ASUBU
ASUBW
ASYNC
ASYSCALL
ATEQ
ATLBP
ATLBR
ATLBWI
ATLBWR
ATNE
AWORD
AXOR
......
......@@ -26,6 +26,12 @@ var Anames = []string{
"BLTZAL",
"BNE",
"BREAK",
"CLO",
"CLZ",
"CMOVF",
"CMOVN",
"CMOVT",
"CMOVZ",
"CMPEQD",
"CMPEQF",
"CMPGED",
......@@ -38,6 +44,7 @@ var Anames = []string{
"DIVU",
"DIVW",
"GOK",
"LL",
"LUI",
"MOVB",
"MOVBU",
......@@ -67,9 +74,12 @@ var Anames = []string{
"REM",
"REMU",
"RFE",
"SC",
"SGT",
"SGTU",
"SLL",
"SQRTD",
"SQRTF",
"SRA",
"SRL",
"SUB",
......@@ -77,11 +87,14 @@ var Anames = []string{
"SUBF",
"SUBU",
"SUBW",
"SYNC",
"SYSCALL",
"TEQ",
"TLBP",
"TLBR",
"TLBWI",
"TLBWR",
"TNE",
"WORD",
"XOR",
"MOVV",
......
......@@ -39,7 +39,7 @@ import (
// Instruction layout.
const (
funcAlign = 8
mips64FuncAlign = 8
)
const (
......@@ -54,270 +54,319 @@ type Optab struct {
type_ int8
size int8
param int16
mode int
}
var optab = []Optab{
{obj.ATEXT, C_LEXT, C_NONE, C_TEXTSIZE, 0, 0, 0},
{obj.ATEXT, C_ADDR, C_NONE, C_TEXTSIZE, 0, 0, 0},
{AMOVW, C_REG, C_NONE, C_REG, 1, 4, 0},
{AMOVV, C_REG, C_NONE, C_REG, 1, 4, 0},
{AMOVB, C_REG, C_NONE, C_REG, 12, 8, 0},
{AMOVBU, C_REG, C_NONE, C_REG, 13, 4, 0},
{AMOVWU, C_REG, C_NONE, C_REG, 14, 8, 0},
{ASUB, C_REG, C_REG, C_REG, 2, 4, 0},
{AADD, C_REG, C_REG, C_REG, 2, 4, 0},
{AAND, C_REG, C_REG, C_REG, 2, 4, 0},
{ASUB, C_REG, C_NONE, C_REG, 2, 4, 0},
{AADD, C_REG, C_NONE, C_REG, 2, 4, 0},
{AAND, C_REG, C_NONE, C_REG, 2, 4, 0},
{ASLL, C_REG, C_NONE, C_REG, 9, 4, 0},
{ASLL, C_REG, C_REG, C_REG, 9, 4, 0},
{AADDF, C_FREG, C_NONE, C_FREG, 32, 4, 0},
{AADDF, C_FREG, C_REG, C_FREG, 32, 4, 0},
{ACMPEQF, C_FREG, C_REG, C_NONE, 32, 4, 0},
{AABSF, C_FREG, C_NONE, C_FREG, 33, 4, 0},
{AMOVF, C_FREG, C_NONE, C_FREG, 33, 4, 0},
{AMOVD, C_FREG, C_NONE, C_FREG, 33, 4, 0},
{AMOVW, C_REG, C_NONE, C_SEXT, 7, 4, REGSB},
{AMOVWU, C_REG, C_NONE, C_SEXT, 7, 4, REGSB},
{AMOVV, C_REG, C_NONE, C_SEXT, 7, 4, REGSB},
{AMOVB, C_REG, C_NONE, C_SEXT, 7, 4, REGSB},
{AMOVBU, C_REG, C_NONE, C_SEXT, 7, 4, REGSB},
{AMOVWL, C_REG, C_NONE, C_SEXT, 7, 4, REGSB},
{AMOVW, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP},
{AMOVWU, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP},
{AMOVV, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP},
{AMOVB, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP},
{AMOVBU, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP},
{AMOVWL, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP},
{AMOVW, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO},
{AMOVWU, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO},
{AMOVV, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO},
{AMOVB, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO},
{AMOVBU, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO},
{AMOVWL, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO},
{AMOVW, C_SEXT, C_NONE, C_REG, 8, 4, REGSB},
{AMOVWU, C_SEXT, C_NONE, C_REG, 8, 4, REGSB},
{AMOVV, C_SEXT, C_NONE, C_REG, 8, 4, REGSB},
{AMOVB, C_SEXT, C_NONE, C_REG, 8, 4, REGSB},
{AMOVBU, C_SEXT, C_NONE, C_REG, 8, 4, REGSB},
{AMOVWL, C_SEXT, C_NONE, C_REG, 8, 4, REGSB},
{AMOVW, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP},
{AMOVWU, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP},
{AMOVV, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP},
{AMOVB, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP},
{AMOVBU, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP},
{AMOVWL, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP},
{AMOVW, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO},
{AMOVWU, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO},
{AMOVV, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO},
{AMOVB, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO},
{AMOVBU, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO},
{AMOVWL, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO},
{AMOVW, C_REG, C_NONE, C_LEXT, 35, 12, REGSB},
{AMOVWU, C_REG, C_NONE, C_LEXT, 35, 12, REGSB},
{AMOVV, C_REG, C_NONE, C_LEXT, 35, 12, REGSB},
{AMOVB, C_REG, C_NONE, C_LEXT, 35, 12, REGSB},
{AMOVBU, C_REG, C_NONE, C_LEXT, 35, 12, REGSB},
{AMOVW, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP},
{AMOVWU, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP},
{AMOVV, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP},
{AMOVB, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP},
{AMOVBU, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP},
{AMOVW, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO},
{AMOVWU, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO},
{AMOVV, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO},
{AMOVB, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO},
{AMOVBU, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO},
{AMOVW, C_REG, C_NONE, C_ADDR, 50, 12, 0},
{AMOVWU, C_REG, C_NONE, C_ADDR, 50, 12, 0},
{AMOVV, C_REG, C_NONE, C_ADDR, 50, 12, 0},
{AMOVB, C_REG, C_NONE, C_ADDR, 50, 12, 0},
{AMOVBU, C_REG, C_NONE, C_ADDR, 50, 12, 0},
{AMOVW, C_REG, C_NONE, C_TLS, 53, 8, 0},
{AMOVWU, C_REG, C_NONE, C_TLS, 53, 8, 0},
{AMOVV, C_REG, C_NONE, C_TLS, 53, 8, 0},
{AMOVB, C_REG, C_NONE, C_TLS, 53, 8, 0},
{AMOVBU, C_REG, C_NONE, C_TLS, 53, 8, 0},
{AMOVW, C_LEXT, C_NONE, C_REG, 36, 12, REGSB},
{AMOVWU, C_LEXT, C_NONE, C_REG, 36, 12, REGSB},
{AMOVV, C_LEXT, C_NONE, C_REG, 36, 12, REGSB},
{AMOVB, C_LEXT, C_NONE, C_REG, 36, 12, REGSB},
{AMOVBU, C_LEXT, C_NONE, C_REG, 36, 12, REGSB},
{AMOVW, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP},
{AMOVWU, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP},
{AMOVV, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP},
{AMOVB, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP},
{AMOVBU, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP},
{AMOVW, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO},
{AMOVWU, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO},
{AMOVV, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO},
{AMOVB, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO},
{AMOVBU, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO},
{AMOVW, C_ADDR, C_NONE, C_REG, 51, 12, 0},
{AMOVWU, C_ADDR, C_NONE, C_REG, 51, 12, 0},
{AMOVV, C_ADDR, C_NONE, C_REG, 51, 12, 0},
{AMOVB, C_ADDR, C_NONE, C_REG, 51, 12, 0},
{AMOVBU, C_ADDR, C_NONE, C_REG, 51, 12, 0},
{AMOVW, C_TLS, C_NONE, C_REG, 54, 8, 0},
{AMOVWU, C_TLS, C_NONE, C_REG, 54, 8, 0},
{AMOVV, C_TLS, C_NONE, C_REG, 54, 8, 0},
{AMOVB, C_TLS, C_NONE, C_REG, 54, 8, 0},
{AMOVBU, C_TLS, C_NONE, C_REG, 54, 8, 0},
{AMOVW, C_SECON, C_NONE, C_REG, 3, 4, REGSB},
{AMOVV, C_SECON, C_NONE, C_REG, 3, 4, REGSB},
{AMOVW, C_SACON, C_NONE, C_REG, 3, 4, REGSP},
{AMOVV, C_SACON, C_NONE, C_REG, 3, 4, REGSP},
{AMOVW, C_LECON, C_NONE, C_REG, 52, 12, REGSB},
{AMOVV, C_LECON, C_NONE, C_REG, 52, 12, REGSB},
{AMOVW, C_LACON, C_NONE, C_REG, 26, 12, REGSP},
{AMOVV, C_LACON, C_NONE, C_REG, 26, 12, REGSP},
{AMOVW, C_ADDCON, C_NONE, C_REG, 3, 4, REGZERO},
{AMOVV, C_ADDCON, C_NONE, C_REG, 3, 4, REGZERO},
{AMOVW, C_ANDCON, C_NONE, C_REG, 3, 4, REGZERO},
{AMOVV, C_ANDCON, C_NONE, C_REG, 3, 4, REGZERO},
{AMOVW, C_STCON, C_NONE, C_REG, 55, 8, 0},
{AMOVV, C_STCON, C_NONE, C_REG, 55, 8, 0},
{AMOVW, C_UCON, C_NONE, C_REG, 24, 4, 0},
{AMOVV, C_UCON, C_NONE, C_REG, 24, 4, 0},
{AMOVW, C_LCON, C_NONE, C_REG, 19, 8, 0},
{AMOVV, C_LCON, C_NONE, C_REG, 19, 8, 0},
{AMOVW, C_HI, C_NONE, C_REG, 20, 4, 0},
{AMOVV, C_HI, C_NONE, C_REG, 20, 4, 0},
{AMOVW, C_LO, C_NONE, C_REG, 20, 4, 0},
{AMOVV, C_LO, C_NONE, C_REG, 20, 4, 0},
{AMOVW, C_REG, C_NONE, C_HI, 21, 4, 0},
{AMOVV, C_REG, C_NONE, C_HI, 21, 4, 0},
{AMOVW, C_REG, C_NONE, C_LO, 21, 4, 0},
{AMOVV, C_REG, C_NONE, C_LO, 21, 4, 0},
{AMUL, C_REG, C_REG, C_NONE, 22, 4, 0},
{AADD, C_ADD0CON, C_REG, C_REG, 4, 4, 0},
{AADD, C_ADD0CON, C_NONE, C_REG, 4, 4, 0},
{AADD, C_ANDCON, C_REG, C_REG, 10, 8, 0},
{AADD, C_ANDCON, C_NONE, C_REG, 10, 8, 0},
{AAND, C_AND0CON, C_REG, C_REG, 4, 4, 0},
{AAND, C_AND0CON, C_NONE, C_REG, 4, 4, 0},
{AAND, C_ADDCON, C_REG, C_REG, 10, 8, 0},
{AAND, C_ADDCON, C_NONE, C_REG, 10, 8, 0},
{AADD, C_UCON, C_REG, C_REG, 25, 8, 0},
{AADD, C_UCON, C_NONE, C_REG, 25, 8, 0},
{AAND, C_UCON, C_REG, C_REG, 25, 8, 0},
{AAND, C_UCON, C_NONE, C_REG, 25, 8, 0},
{AADD, C_LCON, C_NONE, C_REG, 23, 12, 0},
{AAND, C_LCON, C_NONE, C_REG, 23, 12, 0},
{AADD, C_LCON, C_REG, C_REG, 23, 12, 0},
{AAND, C_LCON, C_REG, C_REG, 23, 12, 0},
{ASLL, C_SCON, C_REG, C_REG, 16, 4, 0},
{ASLL, C_SCON, C_NONE, C_REG, 16, 4, 0},
{ASYSCALL, C_NONE, C_NONE, C_NONE, 5, 4, 0},
{ABEQ, C_REG, C_REG, C_SBRA, 6, 4, 0},
{ABEQ, C_REG, C_NONE, C_SBRA, 6, 4, 0},
{ABLEZ, C_REG, C_NONE, C_SBRA, 6, 4, 0},
{ABFPT, C_NONE, C_NONE, C_SBRA, 6, 8, 0},
{AJMP, C_NONE, C_NONE, C_LBRA, 11, 4, 0},
{AJAL, C_NONE, C_NONE, C_LBRA, 11, 4, 0},
{AJMP, C_NONE, C_NONE, C_ZOREG, 18, 4, REGZERO},
{AJAL, C_NONE, C_NONE, C_ZOREG, 18, 4, REGLINK},
{AMOVW, C_SEXT, C_NONE, C_FREG, 27, 4, REGSB},
{AMOVF, C_SEXT, C_NONE, C_FREG, 27, 4, REGSB},
{AMOVD, C_SEXT, C_NONE, C_FREG, 27, 4, REGSB},
{AMOVW, C_SAUTO, C_NONE, C_FREG, 27, 4, REGSP},
{AMOVF, C_SAUTO, C_NONE, C_FREG, 27, 4, REGSP},
{AMOVD, C_SAUTO, C_NONE, C_FREG, 27, 4, REGSP},
{AMOVW, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO},
{AMOVF, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO},
{AMOVD, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO},
{AMOVW, C_LEXT, C_NONE, C_FREG, 27, 12, REGSB},
{AMOVF, C_LEXT, C_NONE, C_FREG, 27, 12, REGSB},
{AMOVD, C_LEXT, C_NONE, C_FREG, 27, 12, REGSB},
{AMOVW, C_LAUTO, C_NONE, C_FREG, 27, 12, REGSP},
{AMOVF, C_LAUTO, C_NONE, C_FREG, 27, 12, REGSP},
{AMOVD, C_LAUTO, C_NONE, C_FREG, 27, 12, REGSP},
{AMOVW, C_LOREG, C_NONE, C_FREG, 27, 12, REGZERO},
{AMOVF, C_LOREG, C_NONE, C_FREG, 27, 12, REGZERO},
{AMOVD, C_LOREG, C_NONE, C_FREG, 27, 12, REGZERO},
{AMOVF, C_ADDR, C_NONE, C_FREG, 51, 12, 0},
{AMOVD, C_ADDR, C_NONE, C_FREG, 51, 12, 0},
{AMOVW, C_FREG, C_NONE, C_SEXT, 28, 4, REGSB},
{AMOVF, C_FREG, C_NONE, C_SEXT, 28, 4, REGSB},
{AMOVD, C_FREG, C_NONE, C_SEXT, 28, 4, REGSB},
{AMOVW, C_FREG, C_NONE, C_SAUTO, 28, 4, REGSP},
{AMOVF, C_FREG, C_NONE, C_SAUTO, 28, 4, REGSP},
{AMOVD, C_FREG, C_NONE, C_SAUTO, 28, 4, REGSP},
{AMOVW, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO},
{AMOVF, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO},
{AMOVD, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO},
{AMOVW, C_FREG, C_NONE, C_LEXT, 28, 12, REGSB},
{AMOVF, C_FREG, C_NONE, C_LEXT, 28, 12, REGSB},
{AMOVD, C_FREG, C_NONE, C_LEXT, 28, 12, REGSB},
{AMOVW, C_FREG, C_NONE, C_LAUTO, 28, 12, REGSP},
{AMOVF, C_FREG, C_NONE, C_LAUTO, 28, 12, REGSP},
{AMOVD, C_FREG, C_NONE, C_LAUTO, 28, 12, REGSP},
{AMOVW, C_FREG, C_NONE, C_LOREG, 28, 12, REGZERO},
{AMOVF, C_FREG, C_NONE, C_LOREG, 28, 12, REGZERO},
{AMOVD, C_FREG, C_NONE, C_LOREG, 28, 12, REGZERO},
{AMOVF, C_FREG, C_NONE, C_ADDR, 50, 12, 0},
{AMOVD, C_FREG, C_NONE, C_ADDR, 50, 12, 0},
{AMOVW, C_REG, C_NONE, C_FREG, 30, 4, 0},
{AMOVW, C_FREG, C_NONE, C_REG, 31, 4, 0},
{AMOVV, C_REG, C_NONE, C_FREG, 47, 4, 0},
{AMOVV, C_FREG, C_NONE, C_REG, 48, 4, 0},
{AMOVW, C_ADDCON, C_NONE, C_FREG, 34, 8, 0},
{AMOVW, C_ANDCON, C_NONE, C_FREG, 34, 8, 0},
{AMOVW, C_REG, C_NONE, C_MREG, 37, 4, 0},
{AMOVV, C_REG, C_NONE, C_MREG, 37, 4, 0},
{AMOVW, C_MREG, C_NONE, C_REG, 38, 4, 0},
{AMOVV, C_MREG, C_NONE, C_REG, 38, 4, 0},
{AWORD, C_LCON, C_NONE, C_NONE, 40, 4, 0},
{AMOVW, C_REG, C_NONE, C_FCREG, 41, 8, 0},
{AMOVV, C_REG, C_NONE, C_FCREG, 41, 8, 0},
{AMOVW, C_FCREG, C_NONE, C_REG, 42, 4, 0},
{AMOVV, C_FCREG, C_NONE, C_REG, 42, 4, 0},
{ABREAK, C_REG, C_NONE, C_SEXT, 7, 4, REGSB}, /* really CACHE instruction */
{ABREAK, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP},
{ABREAK, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO},
{ABREAK, C_NONE, C_NONE, C_NONE, 5, 4, 0},
{obj.AUNDEF, C_NONE, C_NONE, C_NONE, 49, 4, 0},
{obj.AUSEFIELD, C_ADDR, C_NONE, C_NONE, 0, 0, 0},
{obj.APCDATA, C_LCON, C_NONE, C_LCON, 0, 0, 0},
{obj.AFUNCDATA, C_SCON, C_NONE, C_ADDR, 0, 0, 0},
{obj.ANOP, C_NONE, C_NONE, C_NONE, 0, 0, 0},
{obj.ADUFFZERO, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as AJMP
{obj.ADUFFCOPY, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as AJMP
{obj.AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0},
{obj.ATEXT, C_LEXT, C_NONE, C_TEXTSIZE, 0, 0, 0, Mips64},
{obj.ATEXT, C_ADDR, C_NONE, C_TEXTSIZE, 0, 0, 0, 0},
{AMOVW, C_REG, C_NONE, C_REG, 1, 4, 0, 0},
{AMOVV, C_REG, C_NONE, C_REG, 1, 4, 0, Mips64},
{AMOVB, C_REG, C_NONE, C_REG, 12, 8, 0, 0},
{AMOVBU, C_REG, C_NONE, C_REG, 13, 4, 0, 0},
{AMOVWU, C_REG, C_NONE, C_REG, 14, 8, 0, Mips64},
{ASUB, C_REG, C_REG, C_REG, 2, 4, 0, 0},
{ASUBV, C_REG, C_REG, C_REG, 2, 4, 0, Mips64},
{AADD, C_REG, C_REG, C_REG, 2, 4, 0, 0},
{AADDV, C_REG, C_REG, C_REG, 2, 4, 0, Mips64},
{AAND, C_REG, C_REG, C_REG, 2, 4, 0, 0},
{ASUB, C_REG, C_NONE, C_REG, 2, 4, 0, 0},
{ASUBV, C_REG, C_NONE, C_REG, 2, 4, 0, Mips64},
{AADD, C_REG, C_NONE, C_REG, 2, 4, 0, 0},
{AADDV, C_REG, C_NONE, C_REG, 2, 4, 0, Mips64},
{AAND, C_REG, C_NONE, C_REG, 2, 4, 0, 0},
{ACMOVN, C_REG, C_REG, C_REG, 2, 4, 0, 0},
{ASLL, C_REG, C_NONE, C_REG, 9, 4, 0, 0},
{ASLL, C_REG, C_REG, C_REG, 9, 4, 0, 0},
{ASLLV, C_REG, C_NONE, C_REG, 9, 4, 0, Mips64},
{ASLLV, C_REG, C_REG, C_REG, 9, 4, 0, Mips64},
{ACLO, C_REG, C_NONE, C_REG, 9, 4, 0, 0},
{AADDF, C_FREG, C_NONE, C_FREG, 32, 4, 0, 0},
{AADDF, C_FREG, C_REG, C_FREG, 32, 4, 0, 0},
{ACMPEQF, C_FREG, C_REG, C_NONE, 32, 4, 0, 0},
{AABSF, C_FREG, C_NONE, C_FREG, 33, 4, 0, 0},
{AMOVVF, C_FREG, C_NONE, C_FREG, 33, 4, 0, Mips64},
{AMOVF, C_FREG, C_NONE, C_FREG, 33, 4, 0, 0},
{AMOVD, C_FREG, C_NONE, C_FREG, 33, 4, 0, 0},
{AMOVW, C_REG, C_NONE, C_SEXT, 7, 4, REGSB, Mips64},
{AMOVWU, C_REG, C_NONE, C_SEXT, 7, 4, REGSB, Mips64},
{AMOVV, C_REG, C_NONE, C_SEXT, 7, 4, REGSB, Mips64},
{AMOVB, C_REG, C_NONE, C_SEXT, 7, 4, REGSB, Mips64},
{AMOVBU, C_REG, C_NONE, C_SEXT, 7, 4, REGSB, Mips64},
{AMOVWL, C_REG, C_NONE, C_SEXT, 7, 4, REGSB, Mips64},
{AMOVVL, C_REG, C_NONE, C_SEXT, 7, 4, REGSB, Mips64},
{AMOVW, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, 0},
{AMOVWU, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, Mips64},
{AMOVV, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, Mips64},
{AMOVB, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, 0},
{AMOVBU, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, 0},
{AMOVWL, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, 0},
{AMOVVL, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, Mips64},
{AMOVW, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, 0},
{AMOVWU, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, Mips64},
{AMOVV, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, Mips64},
{AMOVB, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, 0},
{AMOVBU, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, 0},
{AMOVWL, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, 0},
{AMOVVL, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, Mips64},
{ASC, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, 0},
{AMOVW, C_SEXT, C_NONE, C_REG, 8, 4, REGSB, Mips64},
{AMOVWU, C_SEXT, C_NONE, C_REG, 8, 4, REGSB, Mips64},
{AMOVV, C_SEXT, C_NONE, C_REG, 8, 4, REGSB, Mips64},
{AMOVB, C_SEXT, C_NONE, C_REG, 8, 4, REGSB, Mips64},
{AMOVBU, C_SEXT, C_NONE, C_REG, 8, 4, REGSB, Mips64},
{AMOVWL, C_SEXT, C_NONE, C_REG, 8, 4, REGSB, Mips64},
{AMOVVL, C_SEXT, C_NONE, C_REG, 8, 4, REGSB, Mips64},
{AMOVW, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP, 0},
{AMOVWU, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP, Mips64},
{AMOVV, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP, Mips64},
{AMOVB, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP, 0},
{AMOVBU, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP, 0},
{AMOVWL, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP, 0},
{AMOVVL, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP, Mips64},
{AMOVW, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, 0},
{AMOVWU, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, Mips64},
{AMOVV, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, Mips64},
{AMOVB, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, 0},
{AMOVBU, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, 0},
{AMOVWL, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, 0},
{AMOVVL, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, Mips64},
{ALL, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, 0},
{AMOVW, C_REG, C_NONE, C_LEXT, 35, 12, REGSB, Mips64},
{AMOVWU, C_REG, C_NONE, C_LEXT, 35, 12, REGSB, Mips64},
{AMOVV, C_REG, C_NONE, C_LEXT, 35, 12, REGSB, Mips64},
{AMOVB, C_REG, C_NONE, C_LEXT, 35, 12, REGSB, Mips64},
{AMOVBU, C_REG, C_NONE, C_LEXT, 35, 12, REGSB, Mips64},
{AMOVW, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP, 0},
{AMOVWU, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP, Mips64},
{AMOVV, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP, Mips64},
{AMOVB, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP, 0},
{AMOVBU, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP, 0},
{AMOVW, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO, 0},
{AMOVWU, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO, Mips64},
{AMOVV, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO, Mips64},
{AMOVB, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO, 0},
{AMOVBU, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO, 0},
{ASC, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO, 0},
{AMOVW, C_REG, C_NONE, C_ADDR, 50, 8, 0, Mips32},
{AMOVW, C_REG, C_NONE, C_ADDR, 50, 12, 0, Mips64},
{AMOVWU, C_REG, C_NONE, C_ADDR, 50, 12, 0, Mips64},
{AMOVV, C_REG, C_NONE, C_ADDR, 50, 12, 0, Mips64},
{AMOVB, C_REG, C_NONE, C_ADDR, 50, 8, 0, Mips32},
{AMOVB, C_REG, C_NONE, C_ADDR, 50, 12, 0, Mips64},
{AMOVBU, C_REG, C_NONE, C_ADDR, 50, 8, 0, Mips32},
{AMOVBU, C_REG, C_NONE, C_ADDR, 50, 12, 0, Mips64},
{AMOVW, C_REG, C_NONE, C_TLS, 53, 8, 0, 0},
{AMOVWU, C_REG, C_NONE, C_TLS, 53, 8, 0, Mips64},
{AMOVV, C_REG, C_NONE, C_TLS, 53, 8, 0, Mips64},
{AMOVB, C_REG, C_NONE, C_TLS, 53, 8, 0, 0},
{AMOVBU, C_REG, C_NONE, C_TLS, 53, 8, 0, 0},
{AMOVW, C_LEXT, C_NONE, C_REG, 36, 12, REGSB, Mips64},
{AMOVWU, C_LEXT, C_NONE, C_REG, 36, 12, REGSB, Mips64},
{AMOVV, C_LEXT, C_NONE, C_REG, 36, 12, REGSB, Mips64},
{AMOVB, C_LEXT, C_NONE, C_REG, 36, 12, REGSB, Mips64},
{AMOVBU, C_LEXT, C_NONE, C_REG, 36, 12, REGSB, Mips64},
{AMOVW, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP, 0},
{AMOVWU, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP, Mips64},
{AMOVV, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP, Mips64},
{AMOVB, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP, 0},
{AMOVBU, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP, 0},
{AMOVW, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO, 0},
{AMOVWU, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO, Mips64},
{AMOVV, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO, Mips64},
{AMOVB, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO, 0},
{AMOVBU, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO, 0},
{AMOVW, C_ADDR, C_NONE, C_REG, 51, 8, 0, Mips32},
{AMOVW, C_ADDR, C_NONE, C_REG, 51, 12, 0, Mips64},
{AMOVWU, C_ADDR, C_NONE, C_REG, 51, 12, 0, Mips64},
{AMOVV, C_ADDR, C_NONE, C_REG, 51, 12, 0, Mips64},
{AMOVB, C_ADDR, C_NONE, C_REG, 51, 8, 0, Mips32},
{AMOVB, C_ADDR, C_NONE, C_REG, 51, 12, 0, Mips64},
{AMOVBU, C_ADDR, C_NONE, C_REG, 51, 8, 0, Mips32},
{AMOVBU, C_ADDR, C_NONE, C_REG, 51, 12, 0, Mips64},
{AMOVW, C_TLS, C_NONE, C_REG, 54, 8, 0, 0},
{AMOVWU, C_TLS, C_NONE, C_REG, 54, 8, 0, Mips64},
{AMOVV, C_TLS, C_NONE, C_REG, 54, 8, 0, Mips64},
{AMOVB, C_TLS, C_NONE, C_REG, 54, 8, 0, 0},
{AMOVBU, C_TLS, C_NONE, C_REG, 54, 8, 0, 0},
{AMOVW, C_SECON, C_NONE, C_REG, 3, 4, REGSB, Mips64},
{AMOVV, C_SECON, C_NONE, C_REG, 3, 4, REGSB, Mips64},
{AMOVW, C_SACON, C_NONE, C_REG, 3, 4, REGSP, 0},
{AMOVV, C_SACON, C_NONE, C_REG, 3, 4, REGSP, Mips64},
{AMOVW, C_LECON, C_NONE, C_REG, 52, 8, REGSB, Mips32},
{AMOVW, C_LECON, C_NONE, C_REG, 52, 12, REGSB, Mips64},
{AMOVV, C_LECON, C_NONE, C_REG, 52, 12, REGSB, Mips64},
{AMOVW, C_LACON, C_NONE, C_REG, 26, 12, REGSP, 0},
{AMOVV, C_LACON, C_NONE, C_REG, 26, 12, REGSP, Mips64},
{AMOVW, C_ADDCON, C_NONE, C_REG, 3, 4, REGZERO, 0},
{AMOVV, C_ADDCON, C_NONE, C_REG, 3, 4, REGZERO, Mips64},
{AMOVW, C_ANDCON, C_NONE, C_REG, 3, 4, REGZERO, 0},
{AMOVV, C_ANDCON, C_NONE, C_REG, 3, 4, REGZERO, Mips64},
{AMOVW, C_STCON, C_NONE, C_REG, 55, 8, 0, 0},
{AMOVV, C_STCON, C_NONE, C_REG, 55, 8, 0, Mips64},
{AMOVW, C_UCON, C_NONE, C_REG, 24, 4, 0, 0},
{AMOVV, C_UCON, C_NONE, C_REG, 24, 4, 0, Mips64},
{AMOVW, C_LCON, C_NONE, C_REG, 19, 8, 0, 0},
{AMOVV, C_LCON, C_NONE, C_REG, 19, 8, 0, Mips64},
{AMOVW, C_HI, C_NONE, C_REG, 20, 4, 0, 0},
{AMOVV, C_HI, C_NONE, C_REG, 20, 4, 0, Mips64},
{AMOVW, C_LO, C_NONE, C_REG, 20, 4, 0, 0},
{AMOVV, C_LO, C_NONE, C_REG, 20, 4, 0, Mips64},
{AMOVW, C_REG, C_NONE, C_HI, 21, 4, 0, 0},
{AMOVV, C_REG, C_NONE, C_HI, 21, 4, 0, Mips64},
{AMOVW, C_REG, C_NONE, C_LO, 21, 4, 0, 0},
{AMOVV, C_REG, C_NONE, C_LO, 21, 4, 0, Mips64},
{AMUL, C_REG, C_REG, C_NONE, 22, 4, 0, 0},
{AMUL, C_REG, C_REG, C_REG, 22, 4, 0, 0},
{AMULV, C_REG, C_REG, C_NONE, 22, 4, 0, Mips64},
{AADD, C_ADD0CON, C_REG, C_REG, 4, 4, 0, 0},
{AADD, C_ADD0CON, C_NONE, C_REG, 4, 4, 0, 0},
{AADD, C_ANDCON, C_REG, C_REG, 10, 8, 0, 0},
{AADD, C_ANDCON, C_NONE, C_REG, 10, 8, 0, 0},
{AADDV, C_ADD0CON, C_REG, C_REG, 4, 4, 0, Mips64},
{AADDV, C_ADD0CON, C_NONE, C_REG, 4, 4, 0, Mips64},
{AADDV, C_ANDCON, C_REG, C_REG, 10, 8, 0, Mips64},
{AADDV, C_ANDCON, C_NONE, C_REG, 10, 8, 0, Mips64},
{AAND, C_AND0CON, C_REG, C_REG, 4, 4, 0, 0},
{AAND, C_AND0CON, C_NONE, C_REG, 4, 4, 0, 0},
{AAND, C_ADDCON, C_REG, C_REG, 10, 8, 0, 0},
{AAND, C_ADDCON, C_NONE, C_REG, 10, 8, 0, 0},
{AADD, C_UCON, C_REG, C_REG, 25, 8, 0, 0},
{AADD, C_UCON, C_NONE, C_REG, 25, 8, 0, 0},
{AADDV, C_UCON, C_REG, C_REG, 25, 8, 0, Mips64},
{AADDV, C_UCON, C_NONE, C_REG, 25, 8, 0, Mips64},
{AAND, C_UCON, C_REG, C_REG, 25, 8, 0, 0},
{AAND, C_UCON, C_NONE, C_REG, 25, 8, 0, 0},
{AADD, C_LCON, C_NONE, C_REG, 23, 12, 0, 0},
{AADDV, C_LCON, C_NONE, C_REG, 23, 12, 0, Mips64},
{AAND, C_LCON, C_NONE, C_REG, 23, 12, 0, 0},
{AADD, C_LCON, C_REG, C_REG, 23, 12, 0, 0},
{AADDV, C_LCON, C_REG, C_REG, 23, 12, 0, Mips64},
{AAND, C_LCON, C_REG, C_REG, 23, 12, 0, 0},
{ASLL, C_SCON, C_REG, C_REG, 16, 4, 0, 0},
{ASLL, C_SCON, C_NONE, C_REG, 16, 4, 0, 0},
{ASLLV, C_SCON, C_REG, C_REG, 16, 4, 0, Mips64},
{ASLLV, C_SCON, C_NONE, C_REG, 16, 4, 0, Mips64},
{ASYSCALL, C_NONE, C_NONE, C_NONE, 5, 4, 0, 0},
{ABEQ, C_REG, C_REG, C_SBRA, 6, 4, 0, 0},
{ABEQ, C_REG, C_NONE, C_SBRA, 6, 4, 0, 0},
{ABLEZ, C_REG, C_NONE, C_SBRA, 6, 4, 0, 0},
{ABFPT, C_NONE, C_NONE, C_SBRA, 6, 8, 0, 0},
{AJMP, C_NONE, C_NONE, C_LBRA, 11, 4, 0, 0},
{AJAL, C_NONE, C_NONE, C_LBRA, 11, 4, 0, 0},
{AJMP, C_NONE, C_NONE, C_ZOREG, 18, 4, REGZERO, 0},
{AJAL, C_NONE, C_NONE, C_ZOREG, 18, 4, REGLINK, 0},
{AMOVW, C_SEXT, C_NONE, C_FREG, 27, 4, REGSB, Mips64},
{AMOVF, C_SEXT, C_NONE, C_FREG, 27, 4, REGSB, Mips64},
{AMOVD, C_SEXT, C_NONE, C_FREG, 27, 4, REGSB, Mips64},
{AMOVW, C_SAUTO, C_NONE, C_FREG, 27, 4, REGSP, Mips64},
{AMOVF, C_SAUTO, C_NONE, C_FREG, 27, 4, REGSP, 0},
{AMOVD, C_SAUTO, C_NONE, C_FREG, 27, 4, REGSP, 0},
{AMOVW, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO, Mips64},
{AMOVF, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO, 0},
{AMOVD, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO, 0},
{AMOVW, C_LEXT, C_NONE, C_FREG, 27, 12, REGSB, Mips64},
{AMOVF, C_LEXT, C_NONE, C_FREG, 27, 12, REGSB, Mips64},
{AMOVD, C_LEXT, C_NONE, C_FREG, 27, 12, REGSB, Mips64},
{AMOVW, C_LAUTO, C_NONE, C_FREG, 27, 12, REGSP, Mips64},
{AMOVF, C_LAUTO, C_NONE, C_FREG, 27, 12, REGSP, 0},
{AMOVD, C_LAUTO, C_NONE, C_FREG, 27, 12, REGSP, 0},
{AMOVW, C_LOREG, C_NONE, C_FREG, 27, 12, REGZERO, Mips64},
{AMOVF, C_LOREG, C_NONE, C_FREG, 27, 12, REGZERO, 0},
{AMOVD, C_LOREG, C_NONE, C_FREG, 27, 12, REGZERO, 0},
{AMOVF, C_ADDR, C_NONE, C_FREG, 51, 8, 0, Mips32},
{AMOVF, C_ADDR, C_NONE, C_FREG, 51, 12, 0, Mips64},
{AMOVD, C_ADDR, C_NONE, C_FREG, 51, 8, 0, Mips32},
{AMOVD, C_ADDR, C_NONE, C_FREG, 51, 12, 0, Mips64},
{AMOVW, C_FREG, C_NONE, C_SEXT, 28, 4, REGSB, Mips64},
{AMOVF, C_FREG, C_NONE, C_SEXT, 28, 4, REGSB, Mips64},
{AMOVD, C_FREG, C_NONE, C_SEXT, 28, 4, REGSB, Mips64},
{AMOVW, C_FREG, C_NONE, C_SAUTO, 28, 4, REGSP, Mips64},
{AMOVF, C_FREG, C_NONE, C_SAUTO, 28, 4, REGSP, 0},
{AMOVD, C_FREG, C_NONE, C_SAUTO, 28, 4, REGSP, 0},
{AMOVW, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO, Mips64},
{AMOVF, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO, 0},
{AMOVD, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO, 0},
{AMOVW, C_FREG, C_NONE, C_LEXT, 28, 12, REGSB, Mips64},
{AMOVF, C_FREG, C_NONE, C_LEXT, 28, 12, REGSB, Mips64},
{AMOVD, C_FREG, C_NONE, C_LEXT, 28, 12, REGSB, Mips64},
{AMOVW, C_FREG, C_NONE, C_LAUTO, 28, 12, REGSP, Mips64},
{AMOVF, C_FREG, C_NONE, C_LAUTO, 28, 12, REGSP, 0},
{AMOVD, C_FREG, C_NONE, C_LAUTO, 28, 12, REGSP, 0},
{AMOVW, C_FREG, C_NONE, C_LOREG, 28, 12, REGZERO, Mips64},
{AMOVF, C_FREG, C_NONE, C_LOREG, 28, 12, REGZERO, 0},
{AMOVD, C_FREG, C_NONE, C_LOREG, 28, 12, REGZERO, 0},
{AMOVF, C_FREG, C_NONE, C_ADDR, 50, 8, 0, Mips32},
{AMOVF, C_FREG, C_NONE, C_ADDR, 50, 12, 0, Mips64},
{AMOVD, C_FREG, C_NONE, C_ADDR, 50, 8, 0, Mips32},
{AMOVD, C_FREG, C_NONE, C_ADDR, 50, 12, 0, Mips64},
{AMOVW, C_REG, C_NONE, C_FREG, 30, 4, 0, 0},
{AMOVW, C_FREG, C_NONE, C_REG, 31, 4, 0, 0},
{AMOVV, C_REG, C_NONE, C_FREG, 47, 4, 0, Mips64},
{AMOVV, C_FREG, C_NONE, C_REG, 48, 4, 0, Mips64},
{AMOVW, C_ADDCON, C_NONE, C_FREG, 34, 8, 0, Mips64},
{AMOVW, C_ANDCON, C_NONE, C_FREG, 34, 8, 0, Mips64},
{AMOVW, C_REG, C_NONE, C_MREG, 37, 4, 0, 0},
{AMOVV, C_REG, C_NONE, C_MREG, 37, 4, 0, Mips64},
{AMOVW, C_MREG, C_NONE, C_REG, 38, 4, 0, 0},
{AMOVV, C_MREG, C_NONE, C_REG, 38, 4, 0, Mips64},
{AWORD, C_LCON, C_NONE, C_NONE, 40, 4, 0, 0},
{AMOVW, C_REG, C_NONE, C_FCREG, 41, 8, 0, 0},
{AMOVV, C_REG, C_NONE, C_FCREG, 41, 8, 0, Mips64},
{AMOVW, C_FCREG, C_NONE, C_REG, 42, 4, 0, 0},
{AMOVV, C_FCREG, C_NONE, C_REG, 42, 4, 0, Mips64},
{ATEQ, C_SCON, C_REG, C_REG, 15, 4, 0, 0},
{ATEQ, C_SCON, C_NONE, C_REG, 15, 4, 0, 0},
{ACMOVT, C_REG, C_NONE, C_REG, 17, 4, 0, 0},
{ABREAK, C_REG, C_NONE, C_SEXT, 7, 4, REGSB, Mips64}, /* really CACHE instruction */
{ABREAK, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, Mips64},
{ABREAK, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, Mips64},
{ABREAK, C_NONE, C_NONE, C_NONE, 5, 4, 0, 0},
{obj.AUNDEF, C_NONE, C_NONE, C_NONE, 49, 4, 0, 0},
{obj.AUSEFIELD, C_ADDR, C_NONE, C_NONE, 0, 0, 0, 0},
{obj.APCDATA, C_LCON, C_NONE, C_LCON, 0, 0, 0, 0},
{obj.AFUNCDATA, C_SCON, C_NONE, C_ADDR, 0, 0, 0, 0},
{obj.ANOP, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0},
{obj.ADUFFZERO, C_NONE, C_NONE, C_LBRA, 11, 4, 0, 0}, // same as AJMP
{obj.ADUFFCOPY, C_NONE, C_NONE, C_LBRA, 11, 4, 0, 0}, // same as AJMP
{obj.AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0, 0},
}
var oprange [ALAST & obj.AMask][]Optab
......@@ -330,7 +379,7 @@ func span0(ctxt *obj.Link, cursym *obj.LSym) {
return
}
ctxt.Cursym = cursym
ctxt.Autosize = int32(p.To.Offset + 8)
ctxt.Autosize = int32(p.To.Offset + ctxt.FixedFrameSize())
if oprange[AOR&obj.AMask] == nil {
buildop(ctxt)
......@@ -417,8 +466,9 @@ func span0(ctxt *obj.Link, cursym *obj.LSym) {
cursym.Size = c
}
c += -c & (funcAlign - 1)
if ctxt.Mode&Mips64 != 0 {
c += -c & (mips64FuncAlign - 1)
}
cursym.Size = c
/*
......@@ -503,7 +553,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
return C_LAUTO
case obj.NAME_PARAM:
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + ctxt.FixedFrameSize()
if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
return C_SAUTO
}
......@@ -567,7 +617,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
return C_LACON
case obj.NAME_PARAM:
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + ctxt.FixedFrameSize()
if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
return C_SACON
}
......@@ -653,7 +703,7 @@ func oplook(ctxt *obj.Link, p *obj.Prog) *Optab {
c3 := &xcmp[a3]
for i := range ops {
op := &ops[i]
if int(op.a2) == a2 && c1[op.a1] && c3[op.a3] {
if int(op.a2) == a2 && c1[op.a1] && c3[op.a3] && (ctxt.Mode&op.mode == op.mode) {
p.Optab = uint16(cap(optab) - cap(ops) + i + 1)
return op
}
......@@ -824,18 +874,22 @@ func buildop(ctxt *obj.Link) {
opset(AABSD, r0)
opset(ATRUNCDW, r0)
opset(ATRUNCFW, r0)
opset(ATRUNCDV, r0)
opset(ATRUNCFV, r0)
opset(AMOVVF, r0)
opset(AMOVFV, r0)
opset(ASQRTF, r0)
opset(ASQRTD, r0)
case AMOVVF:
opset(AMOVVD, r0)
opset(AMOVFV, r0)
opset(AMOVDV, r0)
opset(ATRUNCDV, r0)
opset(ATRUNCFV, r0)
case AADD:
opset(ASGT, r0)
opset(ASGTU, r0)
opset(AADDU, r0)
opset(AADDV, r0)
case AADDV:
opset(AADDVU, r0)
case AADDF:
......@@ -873,9 +927,10 @@ func buildop(ctxt *obj.Link) {
opset(ADIVU, r0)
opset(AMULU, r0)
opset(ADIV, r0)
case AMULV:
opset(ADIVV, r0)
opset(ADIVVU, r0)
opset(AMULV, r0)
opset(AMULVU, r0)
opset(AREMV, r0)
opset(AREMVU, r0)
......@@ -883,17 +938,20 @@ func buildop(ctxt *obj.Link) {
case ASLL:
opset(ASRL, r0)
opset(ASRA, r0)
opset(ASLLV, r0)
case ASLLV:
opset(ASRAV, r0)
opset(ASRLV, r0)
case ASUB:
opset(ASUBU, r0)
opset(ASUBV, r0)
opset(ASUBVU, r0)
opset(ANOR, r0)
case ASUBV:
opset(ASUBVU, r0)
case ASYSCALL:
opset(ASYNC, r0)
opset(ATLBP, r0)
opset(ATLBR, r0)
opset(ATLBWI, r0)
......@@ -911,8 +969,9 @@ func buildop(ctxt *obj.Link) {
case AMOVWL:
opset(AMOVWR, r0)
case AMOVVL:
opset(AMOVVR, r0)
opset(AMOVVL, r0)
case AMOVW,
AMOVD,
......@@ -923,6 +982,8 @@ func buildop(ctxt *obj.Link) {
AJAL,
AJMP,
AMOVWU,
ALL,
ASC,
AWORD,
obj.ANOP,
obj.ATEXT,
......@@ -933,6 +994,18 @@ func buildop(ctxt *obj.Link) {
obj.ADUFFZERO,
obj.ADUFFCOPY:
break
case ACMOVN:
opset(ACMOVZ, r0)
case ACMOVT:
opset(ACMOVF, r0)
case ACLO:
opset(ACLZ, r0)
case ATEQ:
opset(ATNE, r0)
}
}
}
......@@ -995,6 +1068,11 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
o3 := uint32(0)
o4 := uint32(0)
add := AADDU
if ctxt.Mode&Mips64 != 0 {
add = AADDVU
}
switch o.type_ {
default:
ctxt.Diag("unknown type %d %v", o.type_)
......@@ -1005,10 +1083,10 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 1: /* mov r1,r2 ==> OR r1,r0,r2 */
a := AOR
if p.As == AMOVW {
if p.As == AMOVW && ctxt.Mode&Mips64 != 0 {
a = AADDU // sign-extended to high 32 bits
}
o1 = OP_RRR(oprrr(ctxt, a), uint32(p.From.Reg), uint32(REGZERO), uint32(p.To.Reg))
o1 = OP_RRR(oprrr(ctxt, a), uint32(REGZERO), uint32(p.From.Reg), uint32(p.To.Reg))
case 2: /* add/sub r1,[r2],r3 */
r := int(p.Reg)
......@@ -1025,7 +1103,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
if r == 0 {
r = int(o.param)
}
a := AADDVU
a := add
if o.a1 == C_ANDCON {
a = AOR
}
......@@ -1152,6 +1230,15 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
o1 = OP_SRR(opirr(ctxt, -ASLLV), uint32(0), uint32(p.From.Reg), uint32(p.To.Reg))
o2 = OP_SRR(opirr(ctxt, -ASRLV), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
case 15: /* teq $c r,r */
v := regoff(ctxt, &p.From)
r := int(p.Reg)
if r == 0 {
r = REGZERO
}
/* only use 10 bits of trap code */
o1 = OP_IRR(opirr(ctxt, p.As), (uint32(v)&0x3FF)<<6, uint32(p.Reg), uint32(p.To.Reg))
case 16: /* sll $c,[r1],r2 */
v := regoff(ctxt, &p.From)
r := int(p.Reg)
......@@ -1166,6 +1253,9 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
o1 = OP_SRR(opirr(ctxt, p.As), uint32(v), uint32(r), uint32(p.To.Reg))
}
case 17:
o1 = OP_RRR(oprrr(ctxt, p.As), uint32(REGZERO), uint32(p.From.Reg), uint32(p.To.Reg))
case 18: /* jmp [r1],0(r2) */
r := int(p.Reg)
if r == 0 {
......@@ -1196,8 +1286,17 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
}
o1 = OP_RRR(a, uint32(REGZERO), uint32(p.From.Reg), uint32(REGZERO))
case 22: /* mul r1,r2 */
o1 = OP_RRR(oprrr(ctxt, p.As), uint32(p.From.Reg), uint32(p.Reg), uint32(REGZERO))
case 22: /* mul r1,r2 [r3]*/
if p.To.Reg != 0 {
r := int(p.Reg)
if r == 0 {
r = int(p.To.Reg)
}
a := SP(3, 4) | 2 /* mul */
o1 = OP_RRR(a, uint32(p.From.Reg), uint32(r), uint32(p.To.Reg))
} else {
o1 = OP_RRR(oprrr(ctxt, p.As), uint32(p.From.Reg), uint32(p.Reg), uint32(REGZERO))
}
case 23: /* add $lcon,r1,r2 ==> lu+or+add */
v := regoff(ctxt, &p.From)
......@@ -1230,7 +1329,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
if r == 0 {
r = int(o.param)
}
o3 = OP_RRR(oprrr(ctxt, AADDVU), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
o3 = OP_RRR(oprrr(ctxt, add), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
case 27: /* mov [sl]ext/auto/oreg,fr ==> lwc1 o(r) */
v := regoff(ctxt, &p.From)
......@@ -1245,7 +1344,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
switch o.size {
case 12:
o1 = OP_IRR(opirr(ctxt, ALUI), uint32((v+1<<15)>>16), uint32(REGZERO), uint32(REGTMP))
o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP))
o2 = OP_RRR(oprrr(ctxt, add), uint32(r), uint32(REGTMP), uint32(REGTMP))
o3 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(REGTMP), uint32(p.To.Reg))
case 4:
......@@ -1265,7 +1364,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
switch o.size {
case 12:
o1 = OP_IRR(opirr(ctxt, ALUI), uint32((v+1<<15)>>16), uint32(REGZERO), uint32(REGTMP))
o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP))
o2 = OP_RRR(oprrr(ctxt, add), uint32(r), uint32(REGTMP), uint32(REGTMP))
o3 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(REGTMP), uint32(p.From.Reg))
case 4:
......@@ -1306,7 +1405,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
r = int(o.param)
}
o1 = OP_IRR(opirr(ctxt, ALUI), uint32((v+1<<15)>>16), uint32(REGZERO), uint32(REGTMP))
o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP))
o2 = OP_RRR(oprrr(ctxt, add), uint32(r), uint32(REGTMP), uint32(REGTMP))
o3 = OP_IRR(opirr(ctxt, p.As), uint32(v), uint32(REGTMP), uint32(p.From.Reg))
case 36: /* mov lext/auto/oreg,r ==> lw o(REGTMP) */
......@@ -1316,7 +1415,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
r = int(o.param)
}
o1 = OP_IRR(opirr(ctxt, ALUI), uint32((v+1<<15)>>16), uint32(REGZERO), uint32(REGTMP))
o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP))
o2 = OP_RRR(oprrr(ctxt, add), uint32(r), uint32(REGTMP), uint32(REGTMP))
o3 = OP_IRR(opirr(ctxt, -p.As), uint32(v), uint32(REGTMP), uint32(p.To.Reg))
case 37: /* movw r,mr */
......@@ -1363,15 +1462,20 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
rel.Sym = p.To.Sym
rel.Add = p.To.Offset
rel.Type = obj.R_ADDRMIPSU
o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(REGSB), uint32(REGTMP), uint32(REGTMP))
o3 = OP_IRR(opirr(ctxt, p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg))
o2 = OP_IRR(opirr(ctxt, p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg))
rel2 := obj.Addrel(ctxt.Cursym)
rel2.Off = int32(ctxt.Pc + 8)
rel2.Off = int32(ctxt.Pc + 4)
rel2.Siz = 4
rel2.Sym = p.To.Sym
rel2.Add = p.To.Offset
rel2.Type = obj.R_ADDRMIPS
if o.size == 12 {
o3 = o2
o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(REGSB), uint32(REGTMP), uint32(REGTMP))
rel2.Off += 4
}
case 51: /* mov addr,r ==> lu + add REGSB, REGTMP + lw o(REGTMP) */
o1 = OP_IRR(opirr(ctxt, ALUI), uint32(0), uint32(REGZERO), uint32(REGTMP))
rel := obj.Addrel(ctxt.Cursym)
......@@ -1380,15 +1484,20 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
rel.Sym = p.From.Sym
rel.Add = p.From.Offset
rel.Type = obj.R_ADDRMIPSU
o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(REGSB), uint32(REGTMP), uint32(REGTMP))
o3 = OP_IRR(opirr(ctxt, -p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
o2 = OP_IRR(opirr(ctxt, -p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
rel2 := obj.Addrel(ctxt.Cursym)
rel2.Off = int32(ctxt.Pc + 8)
rel2.Off = int32(ctxt.Pc + 4)
rel2.Siz = 4
rel2.Sym = p.From.Sym
rel2.Add = p.From.Offset
rel2.Type = obj.R_ADDRMIPS
if o.size == 12 {
o3 = o2
o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(REGSB), uint32(REGTMP), uint32(REGTMP))
rel2.Off += 4
}
case 52: /* mov $lext, r ==> lu + add REGSB, r + add */
o1 = OP_IRR(opirr(ctxt, ALUI), uint32(0), uint32(REGZERO), uint32(p.To.Reg))
rel := obj.Addrel(ctxt.Cursym)
......@@ -1397,15 +1506,20 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
rel.Sym = p.From.Sym
rel.Add = p.From.Offset
rel.Type = obj.R_ADDRMIPSU
o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(REGSB), uint32(p.To.Reg), uint32(p.To.Reg))
o3 = OP_IRR(opirr(ctxt, AADDVU), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
o2 = OP_IRR(opirr(ctxt, add), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
rel2 := obj.Addrel(ctxt.Cursym)
rel2.Off = int32(ctxt.Pc + 8)
rel2.Off = int32(ctxt.Pc + 4)
rel2.Siz = 4
rel2.Sym = p.From.Sym
rel2.Add = p.From.Offset
rel2.Type = obj.R_ADDRMIPS
if o.size == 12 {
o3 = o2
o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(REGSB), uint32(p.To.Reg), uint32(p.To.Reg))
rel2.Off += 4
}
case 53: /* mov r, tlsvar ==> rdhwr + sw o(r3) */
// clobbers R3 !
// load thread pointer with RDHWR, R3 is used for fast kernel emulation on Linux
......@@ -1432,7 +1546,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 55: /* mov $tlsvar, r ==> rdhwr + add */
// clobbers R3 !
o1 = (037<<26 + 073) | (29 << 11) | (3 << 16) // rdhwr $29, r3
o2 = OP_IRR(opirr(ctxt, AADDVU), uint32(0), uint32(REG_R3), uint32(p.To.Reg))
o2 = OP_IRR(opirr(ctxt, add), uint32(0), uint32(REG_R3), uint32(p.To.Reg))
rel := obj.Addrel(ctxt.Cursym)
rel.Off = int32(ctxt.Pc + 4)
rel.Siz = 4
......@@ -1609,6 +1723,27 @@ func oprrr(ctxt *obj.Link, a obj.As) uint32 {
return FPF(7, 6)
case ACMPGED:
return FPD(7, 6)
case ASQRTF:
return FPF(0, 4)
case ASQRTD:
return FPD(0, 4)
case ASYNC:
return OP(1, 7)
case ACMOVN:
return OP(1, 3)
case ACMOVZ:
return OP(1, 2)
case ACMOVT:
return OP(0, 1) | (1 << 16)
case ACMOVF:
return OP(0, 1) | (0 << 16)
case ACLO:
return SP(3, 4) | OP(4, 1)
case ACLZ:
return SP(3, 4) | OP(4, 0)
}
if a < 0 {
......@@ -1761,6 +1896,15 @@ func opirr(ctxt *obj.Link, a obj.As) uint32 {
return OP(7, 6)
case -ASRAV:
return OP(7, 7)
case ATEQ:
return OP(6, 4)
case ATNE:
return OP(6, 6)
case -ALL:
return SP(6, 0)
case ASC:
return SP(7, 0)
}
if a < 0 {
......
......@@ -35,8 +35,8 @@ import (
)
func init() {
obj.RegisterRegister(obj.RBaseMIPS64, REG_LAST&^1023+1024, Rconv)
obj.RegisterOpcode(obj.ABaseMIPS64, Anames)
obj.RegisterRegister(obj.RBaseMIPS, REG_LAST+1, Rconv)
obj.RegisterOpcode(obj.ABaseMIPS, Anames)
}
func Rconv(r int) string {
......@@ -70,7 +70,7 @@ func Rconv(r int) string {
return "LO"
}
return fmt.Sprintf("Rgok(%d)", r-obj.RBaseMIPS64)
return fmt.Sprintf("Rgok(%d)", r-obj.RBaseMIPS)
}
func DRconv(a int) string {
......
......@@ -37,6 +37,18 @@ import (
)
func progedit(ctxt *obj.Link, p *obj.Prog) {
// Maintain information about code generation mode.
if ctxt.Mode == 0 {
switch ctxt.Arch.Family {
default:
ctxt.Diag("unsupported arch family")
case sys.MIPS:
ctxt.Mode = Mips32
case sys.MIPS64:
ctxt.Mode = Mips64
}
}
p.From.Class = 0
p.To.Class = 0
......@@ -59,7 +71,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
f32 := float32(p.From.Val.(float64))
i32 := math.Float32bits(f32)
if i32 == 0 {
p.As = AMOVV
p.As = AMOVW
p.From.Type = obj.TYPE_REG
p.From.Reg = REGZERO
break
......@@ -76,7 +88,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
case AMOVD:
if p.From.Type == obj.TYPE_FCONST {
i64 := math.Float64bits(p.From.Val.(float64))
if i64 == 0 {
if i64 == 0 && ctxt.Mode&Mips64 != 0 {
p.As = AMOVV
p.From.Type = obj.TYPE_REG
p.From.Reg = REGZERO
......@@ -271,6 +283,15 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
}
}
var mov, add obj.As
if ctxt.Mode&Mips64 != 0 {
add = AADDV
mov = AMOVV
} else {
add = AADDU
mov = AMOVW
}
autosize := int32(0)
var p1 *obj.Prog
var p2 *obj.Prog
......@@ -278,13 +299,14 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
o := p.As
switch o {
case obj.ATEXT:
autosize = int32(textstksiz + 8)
if (p.Mark&LEAF != 0) && autosize <= 8 {
autosize = int32(textstksiz + ctxt.FixedFrameSize())
if (p.Mark&LEAF != 0) && autosize <= int32(ctxt.FixedFrameSize()) {
autosize = 0
} else if autosize&4 != 0 {
} else if autosize&4 != 0 && ctxt.Mode&Mips64 != 0 {
autosize += 4
}
p.To.Offset = int64(autosize) - 8
p.To.Offset = int64(autosize) - ctxt.FixedFrameSize()
if p.From3.Offset&obj.NOSPLIT == 0 {
p = stacksplit(ctxt, p, autosize) // emit split check
......@@ -299,7 +321,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
// during the execution of the function prologue, the traceback
// code will not see a half-updated stack frame.
q = obj.Appendp(ctxt, q)
q.As = AMOVV
q.As = mov
q.Lineno = p.Lineno
q.From.Type = obj.TYPE_REG
q.From.Reg = REGLINK
......@@ -308,7 +330,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Reg = REGSP
q = obj.Appendp(ctxt, q)
q.As = AADDV
q.As = add
q.Lineno = p.Lineno
q.From.Type = obj.TYPE_CONST
q.From.Offset = int64(-autosize)
......@@ -333,13 +355,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
if cursym.Text.From3.Offset&obj.WRAPPER != 0 {
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
//
// MOVV g_panic(g), R1
// BEQ R1, end
// MOVV panic_argp(R1), R2
// ADDV $(autosize+8), R29, R3
// BNE R2, R3, end
// ADDV $8, R29, R2
// MOVV R2, panic_argp(R1)
// MOV g_panic(g), R1
// BEQ R1, end
// MOV panic_argp(R1), R2
// ADD $(autosize+FIXED_FRAME), R29, R3
// BNE R2, R3, end
// ADD $FIXED_FRAME, R29, R2
// MOV R2, panic_argp(R1)
// end:
// NOP
//
......@@ -348,7 +370,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q = obj.Appendp(ctxt, q)
q.As = AMOVV
q.As = mov
q.From.Type = obj.TYPE_MEM
q.From.Reg = REGG
q.From.Offset = 4 * int64(ctxt.Arch.PtrSize) // G.panic
......@@ -364,7 +386,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p1 = q
q = obj.Appendp(ctxt, q)
q.As = AMOVV
q.As = mov
q.From.Type = obj.TYPE_MEM
q.From.Reg = REG_R1
q.From.Offset = 0 // Panic.argp
......@@ -372,9 +394,9 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Reg = REG_R2
q = obj.Appendp(ctxt, q)
q.As = AADDV
q.As = add
q.From.Type = obj.TYPE_CONST
q.From.Offset = int64(autosize) + 8
q.From.Offset = int64(autosize) + ctxt.FixedFrameSize()
q.Reg = REGSP
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R3
......@@ -389,15 +411,15 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p2 = q
q = obj.Appendp(ctxt, q)
q.As = AADDV
q.As = add
q.From.Type = obj.TYPE_CONST
q.From.Offset = 8
q.From.Offset = ctxt.FixedFrameSize()
q.Reg = REGSP
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R2
q = obj.Appendp(ctxt, q)
q.As = AMOVV
q.As = mov
q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R2
q.To.Type = obj.TYPE_MEM
......@@ -438,7 +460,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
break
}
p.As = AADDV
p.As = add
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(autosize)
p.To.Type = obj.TYPE_REG
......@@ -459,7 +481,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
break
}
p.As = AMOVV
p.As = mov
p.From.Type = obj.TYPE_MEM
p.From.Offset = 0
p.From.Reg = REGSP
......@@ -471,7 +493,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
if autosize != 0 {
q = ctxt.NewProg()
q.As = AADDV
q.As = add
q.Lineno = p.Lineno
q.From.Type = obj.TYPE_CONST
q.From.Offset = int64(autosize)
......@@ -501,7 +523,9 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q1.Link = q.Link
q.Link = q1
case AADDV,
case AADD,
AADDU,
AADDV,
AADDVU:
if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.From.Type == obj.TYPE_CONST {
p.Spadj = int32(-p.From.Offset)
......@@ -564,10 +588,27 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
}
func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
// MOVV g_stackguard(g), R1
// Leaf function with no frame is effectively NOSPLIT.
if framesize == 0 {
return p
}
var mov, add, sub obj.As
if ctxt.Mode&Mips64 != 0 {
add = AADDV
mov = AMOVV
sub = ASUBVU
} else {
add = AADDU
mov = AMOVW
sub = ASUBU
}
// MOV g_stackguard(g), R1
p = obj.Appendp(ctxt, p)
p.As = AMOVV
p.As = mov
p.From.Type = obj.TYPE_MEM
p.From.Reg = REGG
p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
......@@ -591,11 +632,11 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Reg = REG_R1
} else if framesize <= obj.StackBig {
// large stack: SP-framesize < stackguard-StackSmall
// ADDV $-framesize, SP, R2
// ADD $-framesize, SP, R2
// SGTU R2, stackguard, R1
p = obj.Appendp(ctxt, p)
p.As = AADDV
p.As = add
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(-framesize)
p.Reg = REGSP
......@@ -619,15 +660,15 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
// Preemption sets stackguard to StackPreempt, a very large value.
// That breaks the math above, so we have to check for that explicitly.
// // stackguard is R1
// MOVV $StackPreempt, R2
// MOV $StackPreempt, R2
// BEQ R1, R2, label-of-call-to-morestack
// ADDV $StackGuard, SP, R2
// SUBVU R1, R2
// MOVV $(framesize+(StackGuard-StackSmall)), R1
// ADD $StackGuard, SP, R2
// SUB R1, R2
// MOV $(framesize+(StackGuard-StackSmall)), R1
// SGTU R2, R1, R1
p = obj.Appendp(ctxt, p)
p.As = AMOVV
p.As = mov
p.From.Type = obj.TYPE_CONST
p.From.Offset = obj.StackPreempt
p.To.Type = obj.TYPE_REG
......@@ -643,7 +684,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.Mark |= BRANCH
p = obj.Appendp(ctxt, p)
p.As = AADDV
p.As = add
p.From.Type = obj.TYPE_CONST
p.From.Offset = obj.StackGuard
p.Reg = REGSP
......@@ -651,14 +692,14 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Reg = REG_R2
p = obj.Appendp(ctxt, p)
p.As = ASUBVU
p.As = sub
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R1
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2
p = obj.Appendp(ctxt, p)
p.As = AMOVV
p.As = mov
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(framesize) + obj.StackGuard - obj.StackSmall
p.To.Type = obj.TYPE_REG
......@@ -683,10 +724,10 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Type = obj.TYPE_BRANCH
p.Mark |= BRANCH
// MOVV LINK, R3
// MOV LINK, R3
p = obj.Appendp(ctxt, p)
p.As = AMOVV
p.As = mov
p.From.Type = obj.TYPE_REG
p.From.Reg = REGLINK
p.To.Type = obj.TYPE_REG
......@@ -1494,3 +1535,19 @@ var Linkmips64le = obj.LinkArch{
Follow: follow,
Progedit: progedit,
}
var Linkmips = obj.LinkArch{
Arch: sys.ArchMIPS,
Preprocess: preprocess,
Assemble: span0,
Follow: follow,
Progedit: progedit,
}
var Linkmipsle = obj.LinkArch{
Arch: sys.ArchMIPSLE,
Preprocess: preprocess,
Assemble: span0,
Follow: follow,
Progedit: progedit,
}
......@@ -384,13 +384,13 @@ var regSpace []regSet
const (
// Because of masking operations in the encodings, each register
// space should start at 0 modulo some power of 2.
RBase386 = 1 * 1024
RBaseAMD64 = 2 * 1024
RBaseARM = 3 * 1024
RBasePPC64 = 4 * 1024 // range [4k, 8k)
RBaseARM64 = 8 * 1024 // range [8k, 13k)
RBaseMIPS64 = 13 * 1024 // range [13k, 14k)
RBaseS390X = 14 * 1024 // range [14k, 15k)
RBase386 = 1 * 1024
RBaseAMD64 = 2 * 1024
RBaseARM = 3 * 1024
RBasePPC64 = 4 * 1024 // range [4k, 8k)
RBaseARM64 = 8 * 1024 // range [8k, 13k)
RBaseMIPS = 13 * 1024 // range [13k, 14k)
RBaseS390X = 14 * 1024 // range [14k, 15k)
)
// RegisterRegister binds a pretty-printer (Rconv) for register
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment