Commit b53acd89 authored by Cherry Zhang's avatar Cherry Zhang

cmd/internal/obj/mips: add support of LLV, SCV, NOOP instructions

LLV and SCV are 64-bit load-linked and store-conditional. They
were used in runtime as #define WORD. Change them to normal
instruction form.

NOOP is hardware no-op. It was written as WORD $0. Make a name
for it for better disassembly output.

Fixes #12561.
Fixes #18238.

Change-Id: I82c667ce756fa83ef37b034b641e8c4366335e83
Reviewed-on: https://go-review.googlesource.com/40297Reviewed-by: default avatarMinux Ma <minux@golang.org>
Run-TryBot: Minux Ma <minux@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 84a51432
...@@ -39,6 +39,9 @@ TEXT foo(SB),DUPOK|NOSPLIT,$0 ...@@ -39,6 +39,9 @@ TEXT foo(SB),DUPOK|NOSPLIT,$0
MOVV 16(R1), R2 MOVV 16(R1), R2
MOVV (R1), R2 MOVV (R1), R2
LL (R1), R2 // c0220000
LLV (R1), R2 // d0220000
// LMOVB rreg ',' rreg // LMOVB rreg ',' rreg
// { // {
// outcode(int($1), &$2, 0, &$4); // outcode(int($1), &$2, 0, &$4);
...@@ -98,6 +101,9 @@ TEXT foo(SB),DUPOK|NOSPLIT,$0 ...@@ -98,6 +101,9 @@ TEXT foo(SB),DUPOK|NOSPLIT,$0
MOVV R1, 16(R2) MOVV R1, 16(R2)
MOVV R1, (R2) MOVV R1, (R2)
SC R1, (R2) // e0410000
SCV R1, (R2) // f0410000
// LMOVB rreg ',' addr // LMOVB rreg ',' addr
// { // {
// outcode(int($1), &$2, 0, &$4); // outcode(int($1), &$2, 0, &$4);
...@@ -238,11 +244,11 @@ TEXT foo(SB),DUPOK|NOSPLIT,$0 ...@@ -238,11 +244,11 @@ TEXT foo(SB),DUPOK|NOSPLIT,$0
label0: label0:
JMP 1(PC) JMP 1(PC)
BEQ R1, 2(PC) BEQ R1, 2(PC)
JMP label0+0 // JMP 64 JMP label0+0 // JMP 68
BEQ R1, 2(PC) BEQ R1, 2(PC)
JAL 1(PC) // CALL 1(PC) JAL 1(PC) // CALL 1(PC)
BEQ R1, 2(PC) BEQ R1, 2(PC)
JAL label0+0 // CALL 64 JAL label0+0 // CALL 68
// LBRA addr // LBRA addr
// { // {
...@@ -266,7 +272,7 @@ label0: ...@@ -266,7 +272,7 @@ label0:
// } // }
label1: label1:
BEQ R1, 1(PC) BEQ R1, 1(PC)
BEQ R1, label1 // BEQ R1, 79 BEQ R1, label1 // BEQ R1, 83
// LBRA rreg ',' sreg ',' rel // LBRA rreg ',' sreg ',' rel
// { // {
...@@ -274,7 +280,7 @@ label1: ...@@ -274,7 +280,7 @@ label1:
// } // }
label2: label2:
BEQ R1, R2, 1(PC) BEQ R1, R2, 1(PC)
BEQ R1, R2, label2 // BEQ R1, R2, 81 BEQ R1, R2, label2 // BEQ R1, R2, 85
// //
// other integer conditional branch // other integer conditional branch
...@@ -285,7 +291,7 @@ label2: ...@@ -285,7 +291,7 @@ label2:
// } // }
label3: label3:
BLTZ R1, 1(PC) BLTZ R1, 1(PC)
BLTZ R1, label3 // BLTZ R1, 83 BLTZ R1, label3 // BLTZ R1, 87
// //
// floating point conditional branch // floating point conditional branch
...@@ -293,7 +299,7 @@ label3: ...@@ -293,7 +299,7 @@ label3:
// LBRA rel // LBRA rel
label4: label4:
BFPT 1(PC) BFPT 1(PC)
BFPT label4 // BFPT 85 BFPT label4 // BFPT 89
// //
...@@ -327,7 +333,9 @@ label4: ...@@ -327,7 +333,9 @@ label4:
// //
// WORD // WORD
// //
WORD $1 WORD $1 // 00000001
NOOP // 00000000
SYNC // 0000000f
// //
// NOP // NOP
......
...@@ -299,6 +299,7 @@ const ( ...@@ -299,6 +299,7 @@ const (
ADIVW ADIVW
AGOK AGOK
ALL ALL
ALLV
ALUI ALUI
AMOVB AMOVB
AMOVBU AMOVBU
...@@ -323,12 +324,14 @@ const ( ...@@ -323,12 +324,14 @@ const (
ANEGD ANEGD
ANEGF ANEGF
ANEGW ANEGW
ANOOP // hardware nop
ANOR ANOR
AOR AOR
AREM AREM
AREMU AREMU
ARFE ARFE
ASC ASC
ASCV
ASGT ASGT
ASGTU ASGTU
ASLL ASLL
......
...@@ -45,6 +45,7 @@ var Anames = []string{ ...@@ -45,6 +45,7 @@ var Anames = []string{
"DIVW", "DIVW",
"GOK", "GOK",
"LL", "LL",
"LLV",
"LUI", "LUI",
"MOVB", "MOVB",
"MOVBU", "MOVBU",
...@@ -69,12 +70,14 @@ var Anames = []string{ ...@@ -69,12 +70,14 @@ var Anames = []string{
"NEGD", "NEGD",
"NEGF", "NEGF",
"NEGW", "NEGW",
"NOOP",
"NOR", "NOR",
"OR", "OR",
"REM", "REM",
"REMU", "REMU",
"RFE", "RFE",
"SC", "SC",
"SCV",
"SGT", "SGT",
"SGTU", "SGTU",
"SLL", "SLL",
......
...@@ -129,6 +129,7 @@ var optab = []Optab{ ...@@ -129,6 +129,7 @@ var optab = []Optab{
{AMOVWL, 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, sys.MIPS64}, {AMOVVL, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, sys.MIPS64},
{ASC, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, 0}, {ASC, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, 0},
{ASCV, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, sys.MIPS64},
{AMOVW, C_SEXT, C_NONE, C_REG, 8, 4, REGSB, sys.MIPS64}, {AMOVW, C_SEXT, C_NONE, C_REG, 8, 4, REGSB, sys.MIPS64},
{AMOVWU, C_SEXT, C_NONE, C_REG, 8, 4, REGSB, sys.MIPS64}, {AMOVWU, C_SEXT, C_NONE, C_REG, 8, 4, REGSB, sys.MIPS64},
...@@ -152,6 +153,7 @@ var optab = []Optab{ ...@@ -152,6 +153,7 @@ var optab = []Optab{
{AMOVWL, 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, sys.MIPS64}, {AMOVVL, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, sys.MIPS64},
{ALL, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, 0}, {ALL, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, 0},
{ALLV, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, sys.MIPS64},
{AMOVW, C_REG, C_NONE, C_LEXT, 35, 12, REGSB, sys.MIPS64}, {AMOVW, C_REG, C_NONE, C_LEXT, 35, 12, REGSB, sys.MIPS64},
{AMOVWU, C_REG, C_NONE, C_LEXT, 35, 12, REGSB, sys.MIPS64}, {AMOVWU, C_REG, C_NONE, C_LEXT, 35, 12, REGSB, sys.MIPS64},
...@@ -963,6 +965,7 @@ func buildop(ctxt *obj.Link) { ...@@ -963,6 +965,7 @@ func buildop(ctxt *obj.Link) {
case ASYSCALL: case ASYSCALL:
opset(ASYNC, r0) opset(ASYNC, r0)
opset(ANOOP, r0)
opset(ATLBP, r0) opset(ATLBP, r0)
opset(ATLBR, r0) opset(ATLBR, r0)
opset(ATLBWI, r0) opset(ATLBWI, r0)
...@@ -994,7 +997,9 @@ func buildop(ctxt *obj.Link) { ...@@ -994,7 +997,9 @@ func buildop(ctxt *obj.Link) {
AJMP, AJMP,
AMOVWU, AMOVWU,
ALL, ALL,
ALLV,
ASC, ASC,
ASCV,
AWORD, AWORD,
obj.ANOP, obj.ANOP,
obj.ATEXT, obj.ATEXT,
...@@ -1741,6 +1746,8 @@ func (c *ctxt0) oprrr(a obj.As) uint32 { ...@@ -1741,6 +1746,8 @@ func (c *ctxt0) oprrr(a obj.As) uint32 {
case ASYNC: case ASYNC:
return OP(1, 7) return OP(1, 7)
case ANOOP:
return 0
case ACMOVN: case ACMOVN:
return OP(1, 3) return OP(1, 3)
...@@ -1913,8 +1920,12 @@ func (c *ctxt0) opirr(a obj.As) uint32 { ...@@ -1913,8 +1920,12 @@ func (c *ctxt0) opirr(a obj.As) uint32 {
return OP(6, 6) return OP(6, 6)
case -ALL: case -ALL:
return SP(6, 0) return SP(6, 0)
case -ALLV:
return SP(6, 4)
case ASC: case ASC:
return SP(7, 0) return SP(7, 0)
case ASCV:
return SP(7, 4)
} }
if a < 0 { if a < 0 {
......
...@@ -786,16 +786,8 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { ...@@ -786,16 +786,8 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
func (c *ctxt0) addnop(p *obj.Prog) { func (c *ctxt0) addnop(p *obj.Prog) {
q := c.newprog() q := c.newprog()
// we want to use the canonical NOP (SLL $0,R0,R0) here, q.As = ANOOP
// however, as the assembler will always replace $0
// as R0, we have to resort to manually encode the SLL
// instruction as WORD $0.
q.As = AWORD
q.Pos = p.Pos q.Pos = p.Pos
q.From.Type = obj.TYPE_CONST
q.From.Name = obj.NAME_NONE
q.From.Offset = 0
q.Link = p.Link q.Link = p.Link
p.Link = q p.Link = q
} }
......
...@@ -6,12 +6,6 @@ ...@@ -6,12 +6,6 @@
#include "textflag.h" #include "textflag.h"
#define LL(base, rt) WORD $((060<<26)|((base)<<21)|((rt)<<16))
#define LLV(base, rt) WORD $((064<<26)|((base)<<21)|((rt)<<16))
#define SC(base, rt) WORD $((070<<26)|((base)<<21)|((rt)<<16))
#define SCV(base, rt) WORD $((074<<26)|((base)<<21)|((rt)<<16))
#define SYNC WORD $0xf
// bool cas(uint32 *ptr, uint32 old, uint32 new) // bool cas(uint32 *ptr, uint32 old, uint32 new)
// Atomically: // Atomically:
// if(*val == old){ // if(*val == old){
...@@ -26,9 +20,9 @@ TEXT ·Cas(SB), NOSPLIT, $0-17 ...@@ -26,9 +20,9 @@ TEXT ·Cas(SB), NOSPLIT, $0-17
SYNC SYNC
cas_again: cas_again:
MOVV R5, R3 MOVV R5, R3
LL(1, 4) // R4 = *R1 LL (R1), R4
BNE R2, R4, cas_fail BNE R2, R4, cas_fail
SC(1, 3) // *R1 = R3 SC R3, (R1)
BEQ R3, cas_again BEQ R3, cas_again
MOVV $1, R1 MOVV $1, R1
MOVB R1, ret+16(FP) MOVB R1, ret+16(FP)
...@@ -53,9 +47,9 @@ TEXT ·Cas64(SB), NOSPLIT, $0-25 ...@@ -53,9 +47,9 @@ TEXT ·Cas64(SB), NOSPLIT, $0-25
SYNC SYNC
cas64_again: cas64_again:
MOVV R5, R3 MOVV R5, R3
LLV(1, 4) // R4 = *R1 LLV (R1), R4
BNE R2, R4, cas64_fail BNE R2, R4, cas64_fail
SCV(1, 3) // *R1 = R3 SCV R3, (R1)
BEQ R3, cas64_again BEQ R3, cas64_again
MOVV $1, R1 MOVV $1, R1
MOVB R1, ret+24(FP) MOVB R1, ret+24(FP)
...@@ -104,10 +98,10 @@ TEXT ·Xadd(SB), NOSPLIT, $0-20 ...@@ -104,10 +98,10 @@ TEXT ·Xadd(SB), NOSPLIT, $0-20
MOVV ptr+0(FP), R2 MOVV ptr+0(FP), R2
MOVW delta+8(FP), R3 MOVW delta+8(FP), R3
SYNC SYNC
LL(2, 1) // R1 = *R2 LL (R2), R1
ADDU R1, R3, R4 ADDU R1, R3, R4
MOVV R4, R1 MOVV R4, R1
SC(2, 4) // *R2 = R4 SC R4, (R2)
BEQ R4, -4(PC) BEQ R4, -4(PC)
MOVW R1, ret+16(FP) MOVW R1, ret+16(FP)
SYNC SYNC
...@@ -117,10 +111,10 @@ TEXT ·Xadd64(SB), NOSPLIT, $0-24 ...@@ -117,10 +111,10 @@ TEXT ·Xadd64(SB), NOSPLIT, $0-24
MOVV ptr+0(FP), R2 MOVV ptr+0(FP), R2
MOVV delta+8(FP), R3 MOVV delta+8(FP), R3
SYNC SYNC
LLV(2, 1) // R1 = *R2 LLV (R2), R1
ADDVU R1, R3, R4 ADDVU R1, R3, R4
MOVV R4, R1 MOVV R4, R1
SCV(2, 4) // *R2 = R4 SCV R4, (R2)
BEQ R4, -4(PC) BEQ R4, -4(PC)
MOVV R1, ret+16(FP) MOVV R1, ret+16(FP)
SYNC SYNC
...@@ -132,8 +126,8 @@ TEXT ·Xchg(SB), NOSPLIT, $0-20 ...@@ -132,8 +126,8 @@ TEXT ·Xchg(SB), NOSPLIT, $0-20
SYNC SYNC
MOVV R5, R3 MOVV R5, R3
LL(2, 1) // R1 = *R2 LL (R2), R1
SC(2, 3) // *R2 = R3 SC R3, (R2)
BEQ R3, -3(PC) BEQ R3, -3(PC)
MOVW R1, ret+16(FP) MOVW R1, ret+16(FP)
SYNC SYNC
...@@ -145,8 +139,8 @@ TEXT ·Xchg64(SB), NOSPLIT, $0-24 ...@@ -145,8 +139,8 @@ TEXT ·Xchg64(SB), NOSPLIT, $0-24
SYNC SYNC
MOVV R5, R3 MOVV R5, R3
LLV(2, 1) // R1 = *R2 LLV (R2), R1
SCV(2, 3) // *R2 = R3 SCV R3, (R2)
BEQ R3, -3(PC) BEQ R3, -3(PC)
MOVV R1, ret+16(FP) MOVV R1, ret+16(FP)
SYNC SYNC
...@@ -193,9 +187,9 @@ TEXT ·Or8(SB), NOSPLIT, $0-9 ...@@ -193,9 +187,9 @@ TEXT ·Or8(SB), NOSPLIT, $0-9
SLLV R4, R2 SLLV R4, R2
SYNC SYNC
LL(3, 4) // R4 = *R3 LL (R3), R4
OR R2, R4 OR R2, R4
SC(3, 4) // *R3 = R4 SC R4, (R3)
BEQ R4, -4(PC) BEQ R4, -4(PC)
SYNC SYNC
RET RET
...@@ -223,9 +217,9 @@ TEXT ·And8(SB), NOSPLIT, $0-9 ...@@ -223,9 +217,9 @@ TEXT ·And8(SB), NOSPLIT, $0-9
OR R5, R2 OR R5, R2
SYNC SYNC
LL(3, 4) // R4 = *R3 LL (R3), R4
AND R2, R4 AND R2, R4
SC(3, 4) // *R3 = R4 SC R4, (R3)
BEQ R4, -4(PC) BEQ R4, -4(PC)
SYNC SYNC
RET RET
...@@ -6,12 +6,6 @@ ...@@ -6,12 +6,6 @@
#include "textflag.h" #include "textflag.h"
#define LL(base, rt) WORD $((060<<26)|((base)<<21)|((rt)<<16))
#define LLV(base, rt) WORD $((064<<26)|((base)<<21)|((rt)<<16))
#define SC(base, rt) WORD $((070<<26)|((base)<<21)|((rt)<<16))
#define SCV(base, rt) WORD $((074<<26)|((base)<<21)|((rt)<<16))
#define SYNC WORD $0xf
TEXT ·SwapInt32(SB),NOSPLIT,$0-20 TEXT ·SwapInt32(SB),NOSPLIT,$0-20
JMP ·SwapUint32(SB) JMP ·SwapUint32(SB)
...@@ -20,8 +14,8 @@ TEXT ·SwapUint32(SB),NOSPLIT,$0-20 ...@@ -20,8 +14,8 @@ TEXT ·SwapUint32(SB),NOSPLIT,$0-20
MOVW new+8(FP), R5 MOVW new+8(FP), R5
SYNC SYNC
MOVV R5, R3 MOVV R5, R3
LL(2, 1) // R1 = *R2 LL (R2), R1
SC(2, 3) // *R2 = R3 SC R3, (R2)
BEQ R3, -3(PC) BEQ R3, -3(PC)
MOVW R1, old+16(FP) MOVW R1, old+16(FP)
SYNC SYNC
...@@ -35,8 +29,8 @@ TEXT ·SwapUint64(SB),NOSPLIT,$0-24 ...@@ -35,8 +29,8 @@ TEXT ·SwapUint64(SB),NOSPLIT,$0-24
MOVV new+8(FP), R5 MOVV new+8(FP), R5
SYNC SYNC
MOVV R5, R3 MOVV R5, R3
LLV(2, 1) // R1 = *R2 LLV (R2), R1
SCV(2, 3) // *R2 = R3 SCV R3, (R2)
BEQ R3, -3(PC) BEQ R3, -3(PC)
MOVV R1, old+16(FP) MOVV R1, old+16(FP)
SYNC SYNC
...@@ -55,9 +49,9 @@ TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0-17 ...@@ -55,9 +49,9 @@ TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0-17
SYNC SYNC
cas_again: cas_again:
MOVV R5, R3 MOVV R5, R3
LL(1, 4) // R4 = *R1 LL (R1), R4
BNE R2, R4, cas_fail BNE R2, R4, cas_fail
SC(1, 3) // *R1 = R3 SC R3, (R1)
BEQ R3, cas_again BEQ R3, cas_again
MOVV $1, R1 MOVV $1, R1
MOVB R1, swapped+16(FP) MOVB R1, swapped+16(FP)
...@@ -80,9 +74,9 @@ TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$0-25 ...@@ -80,9 +74,9 @@ TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$0-25
SYNC SYNC
cas64_again: cas64_again:
MOVV R5, R3 MOVV R5, R3
LLV(1, 4) // R4 = *R1 LLV (R1), R4
BNE R2, R4, cas64_fail BNE R2, R4, cas64_fail
SCV(1, 3) // *R1 = R3 SCV R3, (R1)
BEQ R3, cas64_again BEQ R3, cas64_again
MOVV $1, R1 MOVV $1, R1
MOVB R1, swapped+24(FP) MOVB R1, swapped+24(FP)
...@@ -99,10 +93,10 @@ TEXT ·AddUint32(SB),NOSPLIT,$0-20 ...@@ -99,10 +93,10 @@ TEXT ·AddUint32(SB),NOSPLIT,$0-20
MOVV addr+0(FP), R2 MOVV addr+0(FP), R2
MOVW delta+8(FP), R3 MOVW delta+8(FP), R3
SYNC SYNC
LL(2, 1) // R1 = *R2 LL (R2), R1
ADDU R1, R3, R4 ADDU R1, R3, R4
MOVV R4, R1 MOVV R4, R1
SC(2, 4) // *R2 = R4 SC R4, (R2)
BEQ R4, -4(PC) BEQ R4, -4(PC)
MOVW R1, new+16(FP) MOVW R1, new+16(FP)
SYNC SYNC
...@@ -118,10 +112,10 @@ TEXT ·AddUint64(SB),NOSPLIT,$0-24 ...@@ -118,10 +112,10 @@ TEXT ·AddUint64(SB),NOSPLIT,$0-24
MOVV addr+0(FP), R2 MOVV addr+0(FP), R2
MOVV delta+8(FP), R3 MOVV delta+8(FP), R3
SYNC SYNC
LLV(2, 1) // R1 = *R2 LLV (R2), R1
ADDVU R1, R3, R4 ADDVU R1, R3, R4
MOVV R4, R1 MOVV R4, R1
SCV(2, 4) // *R2 = R4 SCV R4, (R2)
BEQ R4, -4(PC) BEQ R4, -4(PC)
MOVV R1, new+16(FP) MOVV R1, new+16(FP)
SYNC SYNC
......
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