mirror of
https://github.com/golang/go.git
synced 2025-05-21 07:13:27 +00:00
cmd/asm: add masked branch and conditional load instructions to s390x
The branch-relative-on-condition (BRC) instruction allows us to use an immediate to specify under what conditions the branch is taken. For example, `BRC $7, L1` is equivalent to `BNE L1`. It is sometimes useful to specify branches in this way when either we don't have an extended mnemonic for a particular mask value or we want to generate the condition code mask programmatically. The new load-on-condition (LOCR and LOCGR) and compare-and-branch (CRJ, CGRJ, CLRJ, CLGRJ, CIJ, CGIJ, CLIJ and CLGIJ) instructions provide the same flexibility for conditional loads and combined compare and branch instructions. Change-Id: Ic6f5d399b0157e278b39bd3645f4ee0f4df8e5fc Reviewed-on: https://go-review.googlesource.com/c/go/+/196558 Run-TryBot: Michael Munday <mike.munday@ibm.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
eb96f8a574
commit
8c99e45ef9
@ -15,7 +15,8 @@ import (
|
|||||||
|
|
||||||
func jumpS390x(word string) bool {
|
func jumpS390x(word string) bool {
|
||||||
switch word {
|
switch word {
|
||||||
case "BC",
|
case "BRC",
|
||||||
|
"BC",
|
||||||
"BCL",
|
"BCL",
|
||||||
"BEQ",
|
"BEQ",
|
||||||
"BGE",
|
"BGE",
|
||||||
@ -41,6 +42,14 @@ func jumpS390x(word string) bool {
|
|||||||
"CMPUBLE",
|
"CMPUBLE",
|
||||||
"CMPUBLT",
|
"CMPUBLT",
|
||||||
"CMPUBNE",
|
"CMPUBNE",
|
||||||
|
"CRJ",
|
||||||
|
"CGRJ",
|
||||||
|
"CLRJ",
|
||||||
|
"CLGRJ",
|
||||||
|
"CIJ",
|
||||||
|
"CGIJ",
|
||||||
|
"CLIJ",
|
||||||
|
"CLGIJ",
|
||||||
"CALL",
|
"CALL",
|
||||||
"JMP":
|
"JMP":
|
||||||
return true
|
return true
|
||||||
|
@ -450,8 +450,19 @@ func (p *Parser) asmJump(op obj.As, cond string, a []obj.Addr) {
|
|||||||
target = &a[2]
|
target = &a[2]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
p.errorf("wrong number of arguments to %s instruction", op)
|
||||||
fallthrough
|
return
|
||||||
|
case 4:
|
||||||
|
if p.arch.Family == sys.S390X {
|
||||||
|
// 4-operand compare-and-branch.
|
||||||
|
prog.From = a[0]
|
||||||
|
prog.Reg = p.getRegister(prog, op, &a[1])
|
||||||
|
prog.SetFrom3(a[2])
|
||||||
|
target = &a[3]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
p.errorf("wrong number of arguments to %s instruction", op)
|
||||||
|
return
|
||||||
default:
|
default:
|
||||||
p.errorf("wrong number of arguments to %s instruction", op)
|
p.errorf("wrong number of arguments to %s instruction", op)
|
||||||
return
|
return
|
||||||
|
14
src/cmd/asm/internal/asm/testdata/s390x.s
vendored
14
src/cmd/asm/internal/asm/testdata/s390x.s
vendored
@ -22,6 +22,9 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
|
|||||||
MOVDLT R8, R9 // b9e24098
|
MOVDLT R8, R9 // b9e24098
|
||||||
MOVDNE R10, R11 // b9e270ba
|
MOVDNE R10, R11 // b9e270ba
|
||||||
|
|
||||||
|
LOCR $3, R2, R1 // b9f23012
|
||||||
|
LOCGR $7, R5, R6 // b9e27065
|
||||||
|
|
||||||
MOVD (R15), R1 // e310f0000004
|
MOVD (R15), R1 // e310f0000004
|
||||||
MOVW (R15), R2 // e320f0000014
|
MOVW (R15), R2 // e320f0000014
|
||||||
MOVH (R15), R3 // e330f0000015
|
MOVH (R15), R3 // e330f0000015
|
||||||
@ -253,6 +256,7 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
|
|||||||
IPM R3 // b2220030
|
IPM R3 // b2220030
|
||||||
IPM R12 // b22200c0
|
IPM R12 // b22200c0
|
||||||
|
|
||||||
|
BRC $7, 0(PC) // a7740000
|
||||||
BNE 0(PC) // a7740000
|
BNE 0(PC) // a7740000
|
||||||
BEQ 0(PC) // a7840000
|
BEQ 0(PC) // a7840000
|
||||||
BLT 0(PC) // a7440000
|
BLT 0(PC) // a7440000
|
||||||
@ -290,6 +294,16 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
|
|||||||
CMPUBGT R9, $256, 0(PC) // ec920000007d
|
CMPUBGT R9, $256, 0(PC) // ec920000007d
|
||||||
CMPUBGE R2, $0, 0(PC) // ec2a0000007d
|
CMPUBGE R2, $0, 0(PC) // ec2a0000007d
|
||||||
|
|
||||||
|
CRJ $15, R1, R2, 0(PC) // ec120000f076
|
||||||
|
CGRJ $12, R3, R4, 0(PC) // ec340000c064
|
||||||
|
CLRJ $3, R5, R6, 0(PC) // ec5600003077
|
||||||
|
CLGRJ $0, R7, R8, 0(PC) // ec7800000065
|
||||||
|
|
||||||
|
CIJ $4, R9, $127, 0(PC) // ec9400007f7e
|
||||||
|
CGIJ $8, R11, $-128, 0(PC) // ecb80000807c
|
||||||
|
CLIJ $1, R1, $255, 0(PC) // ec110000ff7f
|
||||||
|
CLGIJ $2, R3, $0, 0(PC) // ec320000007d
|
||||||
|
|
||||||
LGDR F1, R12 // b3cd00c1
|
LGDR F1, R12 // b3cd00c1
|
||||||
LDGR R2, F15 // b3c100f2
|
LDGR R2, F15 // b3c100f2
|
||||||
|
|
||||||
|
@ -268,6 +268,8 @@ const (
|
|||||||
AMOVDLE
|
AMOVDLE
|
||||||
AMOVDLT
|
AMOVDLT
|
||||||
AMOVDNE
|
AMOVDNE
|
||||||
|
ALOCR
|
||||||
|
ALOCGR
|
||||||
|
|
||||||
// find leftmost one
|
// find leftmost one
|
||||||
AFLOGR
|
AFLOGR
|
||||||
@ -394,6 +396,7 @@ const (
|
|||||||
// branch
|
// branch
|
||||||
ABC
|
ABC
|
||||||
ABCL
|
ABCL
|
||||||
|
ABRC
|
||||||
ABEQ
|
ABEQ
|
||||||
ABGE
|
ABGE
|
||||||
ABGT
|
ABGT
|
||||||
@ -407,6 +410,14 @@ const (
|
|||||||
ASYSCALL
|
ASYSCALL
|
||||||
|
|
||||||
// compare and branch
|
// compare and branch
|
||||||
|
ACRJ
|
||||||
|
ACGRJ
|
||||||
|
ACLRJ
|
||||||
|
ACLGRJ
|
||||||
|
ACIJ
|
||||||
|
ACGIJ
|
||||||
|
ACLIJ
|
||||||
|
ACLGIJ
|
||||||
ACMPBEQ
|
ACMPBEQ
|
||||||
ACMPBGE
|
ACMPBGE
|
||||||
ACMPBGT
|
ACMPBGT
|
||||||
|
@ -45,6 +45,8 @@ var Anames = []string{
|
|||||||
"MOVDLE",
|
"MOVDLE",
|
||||||
"MOVDLT",
|
"MOVDLT",
|
||||||
"MOVDNE",
|
"MOVDNE",
|
||||||
|
"LOCR",
|
||||||
|
"LOCGR",
|
||||||
"FLOGR",
|
"FLOGR",
|
||||||
"POPCNT",
|
"POPCNT",
|
||||||
"AND",
|
"AND",
|
||||||
@ -141,6 +143,7 @@ var Anames = []string{
|
|||||||
"SYNC",
|
"SYNC",
|
||||||
"BC",
|
"BC",
|
||||||
"BCL",
|
"BCL",
|
||||||
|
"BRC",
|
||||||
"BEQ",
|
"BEQ",
|
||||||
"BGE",
|
"BGE",
|
||||||
"BGT",
|
"BGT",
|
||||||
@ -152,6 +155,14 @@ var Anames = []string{
|
|||||||
"BVC",
|
"BVC",
|
||||||
"BVS",
|
"BVS",
|
||||||
"SYSCALL",
|
"SYSCALL",
|
||||||
|
"CRJ",
|
||||||
|
"CGRJ",
|
||||||
|
"CLRJ",
|
||||||
|
"CLGRJ",
|
||||||
|
"CIJ",
|
||||||
|
"CGIJ",
|
||||||
|
"CLIJ",
|
||||||
|
"CLGIJ",
|
||||||
"CMPBEQ",
|
"CMPBEQ",
|
||||||
"CMPBGE",
|
"CMPBGE",
|
||||||
"CMPBGT",
|
"CMPBGT",
|
||||||
|
@ -236,21 +236,32 @@ var optab = []Optab{
|
|||||||
|
|
||||||
// branch
|
// branch
|
||||||
{i: 16, as: ABEQ, a6: C_SBRA},
|
{i: 16, as: ABEQ, a6: C_SBRA},
|
||||||
|
{i: 16, as: ABRC, a1: C_SCON, a6: C_SBRA},
|
||||||
{i: 11, as: ABR, a6: C_LBRA},
|
{i: 11, as: ABR, a6: C_LBRA},
|
||||||
{i: 16, as: ABC, a1: C_SCON, a2: C_REG, a6: C_LBRA},
|
{i: 16, as: ABC, a1: C_SCON, a2: C_REG, a6: C_LBRA},
|
||||||
{i: 18, as: ABR, a6: C_REG},
|
{i: 18, as: ABR, a6: C_REG},
|
||||||
{i: 18, as: ABR, a1: C_REG, a6: C_REG},
|
{i: 18, as: ABR, a1: C_REG, a6: C_REG},
|
||||||
{i: 15, as: ABR, a6: C_ZOREG},
|
{i: 15, as: ABR, a6: C_ZOREG},
|
||||||
{i: 15, as: ABC, a6: C_ZOREG},
|
{i: 15, as: ABC, a6: C_ZOREG},
|
||||||
|
|
||||||
|
// compare and branch
|
||||||
|
{i: 89, as: ACGRJ, a1: C_SCON, a2: C_REG, a3: C_REG, a6: C_SBRA},
|
||||||
{i: 89, as: ACMPBEQ, a1: C_REG, a2: C_REG, a6: C_SBRA},
|
{i: 89, as: ACMPBEQ, a1: C_REG, a2: C_REG, a6: C_SBRA},
|
||||||
|
{i: 89, as: ACLGRJ, a1: C_SCON, a2: C_REG, a3: C_REG, a6: C_SBRA},
|
||||||
|
{i: 89, as: ACMPUBEQ, a1: C_REG, a2: C_REG, a6: C_SBRA},
|
||||||
|
{i: 90, as: ACGIJ, a1: C_SCON, a2: C_REG, a3: C_ADDCON, a6: C_SBRA},
|
||||||
|
{i: 90, as: ACGIJ, a1: C_SCON, a2: C_REG, a3: C_SCON, a6: C_SBRA},
|
||||||
{i: 90, as: ACMPBEQ, a1: C_REG, a3: C_ADDCON, a6: C_SBRA},
|
{i: 90, as: ACMPBEQ, a1: C_REG, a3: C_ADDCON, a6: C_SBRA},
|
||||||
{i: 90, as: ACMPBEQ, a1: C_REG, a3: C_SCON, a6: C_SBRA},
|
{i: 90, as: ACMPBEQ, a1: C_REG, a3: C_SCON, a6: C_SBRA},
|
||||||
{i: 89, as: ACMPUBEQ, a1: C_REG, a2: C_REG, a6: C_SBRA},
|
{i: 90, as: ACLGIJ, a1: C_SCON, a2: C_REG, a3: C_ADDCON, a6: C_SBRA},
|
||||||
{i: 90, as: ACMPUBEQ, a1: C_REG, a3: C_ANDCON, a6: C_SBRA},
|
{i: 90, as: ACMPUBEQ, a1: C_REG, a3: C_ANDCON, a6: C_SBRA},
|
||||||
|
|
||||||
// move on condition
|
// move on condition
|
||||||
{i: 17, as: AMOVDEQ, a1: C_REG, a6: C_REG},
|
{i: 17, as: AMOVDEQ, a1: C_REG, a6: C_REG},
|
||||||
|
|
||||||
|
// load on condition
|
||||||
|
{i: 25, as: ALOCGR, a1: C_SCON, a2: C_REG, a6: C_REG},
|
||||||
|
|
||||||
// find leftmost one
|
// find leftmost one
|
||||||
{i: 8, as: AFLOGR, a1: C_REG, a6: C_REG},
|
{i: 8, as: AFLOGR, a1: C_REG, a6: C_REG},
|
||||||
|
|
||||||
@ -1022,12 +1033,22 @@ func buildop(ctxt *obj.Link) {
|
|||||||
opset(ACMPUBLE, r)
|
opset(ACMPUBLE, r)
|
||||||
opset(ACMPUBLT, r)
|
opset(ACMPUBLT, r)
|
||||||
opset(ACMPUBNE, r)
|
opset(ACMPUBNE, r)
|
||||||
|
case ACGRJ:
|
||||||
|
opset(ACRJ, r)
|
||||||
|
case ACLGRJ:
|
||||||
|
opset(ACLRJ, r)
|
||||||
|
case ACGIJ:
|
||||||
|
opset(ACIJ, r)
|
||||||
|
case ACLGIJ:
|
||||||
|
opset(ACLIJ, r)
|
||||||
case AMOVDEQ:
|
case AMOVDEQ:
|
||||||
opset(AMOVDGE, r)
|
opset(AMOVDGE, r)
|
||||||
opset(AMOVDGT, r)
|
opset(AMOVDGT, r)
|
||||||
opset(AMOVDLE, r)
|
opset(AMOVDLE, r)
|
||||||
opset(AMOVDLT, r)
|
opset(AMOVDLT, r)
|
||||||
opset(AMOVDNE, r)
|
opset(AMOVDNE, r)
|
||||||
|
case ALOCGR:
|
||||||
|
opset(ALOCR, r)
|
||||||
case ALTDBR:
|
case ALTDBR:
|
||||||
opset(ALTEBR, r)
|
opset(ALTEBR, r)
|
||||||
case ATCDB:
|
case ATCDB:
|
||||||
@ -2620,6 +2641,10 @@ func (c *ctxtz) addcallreloc(sym *obj.LSym, add int64) *obj.Reloc {
|
|||||||
|
|
||||||
func (c *ctxtz) branchMask(p *obj.Prog) uint32 {
|
func (c *ctxtz) branchMask(p *obj.Prog) uint32 {
|
||||||
switch p.As {
|
switch p.As {
|
||||||
|
case ABRC, ALOCR, ALOCGR,
|
||||||
|
ACRJ, ACGRJ, ACIJ, ACGIJ,
|
||||||
|
ACLRJ, ACLGRJ, ACLIJ, ACLGIJ:
|
||||||
|
return uint32(p.From.Offset)
|
||||||
case ABEQ, ACMPBEQ, ACMPUBEQ, AMOVDEQ:
|
case ABEQ, ACMPBEQ, ACMPUBEQ, AMOVDEQ:
|
||||||
return 0x8
|
return 0x8
|
||||||
case ABGE, ACMPBGE, ACMPUBGE, AMOVDGE:
|
case ABGE, ACMPBGE, ACMPUBGE, AMOVDGE:
|
||||||
@ -3207,6 +3232,17 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) {
|
|||||||
zRIL(_a, op_XILF, uint32(p.To.Reg), uint32(v), asm)
|
zRIL(_a, op_XILF, uint32(p.To.Reg), uint32(v), asm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 25: // load on condition (register)
|
||||||
|
m3 := c.branchMask(p)
|
||||||
|
var opcode uint32
|
||||||
|
switch p.As {
|
||||||
|
case ALOCR:
|
||||||
|
opcode = op_LOCR
|
||||||
|
case ALOCGR:
|
||||||
|
opcode = op_LOCGR
|
||||||
|
}
|
||||||
|
zRRF(opcode, m3, 0, uint32(p.To.Reg), uint32(p.Reg), asm)
|
||||||
|
|
||||||
case 26: // MOVD $offset(base)(index), reg
|
case 26: // MOVD $offset(base)(index), reg
|
||||||
v := c.regoff(&p.From)
|
v := c.regoff(&p.From)
|
||||||
r := p.From.Reg
|
r := p.From.Reg
|
||||||
@ -3788,21 +3824,44 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) {
|
|||||||
if p.Pcond != nil {
|
if p.Pcond != nil {
|
||||||
v = int32((p.Pcond.Pc - p.Pc) >> 1)
|
v = int32((p.Pcond.Pc - p.Pc) >> 1)
|
||||||
}
|
}
|
||||||
var opcode, opcode2 uint32
|
|
||||||
switch p.As {
|
// Some instructions take a mask as the first argument.
|
||||||
case ACMPBEQ, ACMPBGE, ACMPBGT, ACMPBLE, ACMPBLT, ACMPBNE:
|
r1, r2 := p.From.Reg, p.Reg
|
||||||
opcode = op_CGRJ
|
if p.From.Type == obj.TYPE_CONST {
|
||||||
opcode2 = op_CGR
|
r1, r2 = p.Reg, p.RestArgs[0].Reg
|
||||||
case ACMPUBEQ, ACMPUBGE, ACMPUBGT, ACMPUBLE, ACMPUBLT, ACMPUBNE:
|
|
||||||
opcode = op_CLGRJ
|
|
||||||
opcode2 = op_CLGR
|
|
||||||
}
|
}
|
||||||
mask := c.branchMask(p)
|
m3 := c.branchMask(p)
|
||||||
|
|
||||||
|
var opcode uint32
|
||||||
|
switch p.As {
|
||||||
|
case ACRJ:
|
||||||
|
// COMPARE AND BRANCH RELATIVE (32)
|
||||||
|
opcode = op_CRJ
|
||||||
|
case ACGRJ, ACMPBEQ, ACMPBGE, ACMPBGT, ACMPBLE, ACMPBLT, ACMPBNE:
|
||||||
|
// COMPARE AND BRANCH RELATIVE (64)
|
||||||
|
opcode = op_CGRJ
|
||||||
|
case ACLRJ:
|
||||||
|
// COMPARE LOGICAL AND BRANCH RELATIVE (32)
|
||||||
|
opcode = op_CLRJ
|
||||||
|
case ACLGRJ, ACMPUBEQ, ACMPUBGE, ACMPUBGT, ACMPUBLE, ACMPUBLT, ACMPUBNE:
|
||||||
|
// COMPARE LOGICAL AND BRANCH RELATIVE (64)
|
||||||
|
opcode = op_CLGRJ
|
||||||
|
}
|
||||||
|
|
||||||
if int32(int16(v)) != v {
|
if int32(int16(v)) != v {
|
||||||
zRRE(opcode2, uint32(p.From.Reg), uint32(p.Reg), asm)
|
// The branch is too far for one instruction so crack
|
||||||
zRIL(_c, op_BRCL, mask, uint32(v-sizeRRE/2), asm)
|
// `CMPBEQ x, y, target` into:
|
||||||
|
//
|
||||||
|
// CMPBNE x, y, 2(PC)
|
||||||
|
// BR target
|
||||||
|
//
|
||||||
|
// Note that the instruction sequence MUST NOT clobber
|
||||||
|
// the condition code.
|
||||||
|
m3 ^= 0xe // invert 3-bit mask
|
||||||
|
zRIE(_b, opcode, uint32(r1), uint32(r2), uint32(sizeRIE+sizeRIL)/2, 0, 0, m3, 0, asm)
|
||||||
|
zRIL(_c, op_BRCL, 0xf, uint32(v-sizeRIE/2), asm)
|
||||||
} else {
|
} else {
|
||||||
zRIE(_b, opcode, uint32(p.From.Reg), uint32(p.Reg), uint32(v), 0, 0, mask, 0, asm)
|
zRIE(_b, opcode, uint32(r1), uint32(r2), uint32(v), 0, 0, m3, 0, asm)
|
||||||
}
|
}
|
||||||
|
|
||||||
case 90: // compare and branch reg $constant
|
case 90: // compare and branch reg $constant
|
||||||
@ -3810,21 +3869,39 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) {
|
|||||||
if p.Pcond != nil {
|
if p.Pcond != nil {
|
||||||
v = int32((p.Pcond.Pc - p.Pc) >> 1)
|
v = int32((p.Pcond.Pc - p.Pc) >> 1)
|
||||||
}
|
}
|
||||||
var opcode, opcode2 uint32
|
|
||||||
switch p.As {
|
// Some instructions take a mask as the first argument.
|
||||||
case ACMPBEQ, ACMPBGE, ACMPBGT, ACMPBLE, ACMPBLT, ACMPBNE:
|
r1, i2 := p.From.Reg, p.RestArgs[0].Offset
|
||||||
opcode = op_CGIJ
|
if p.From.Type == obj.TYPE_CONST {
|
||||||
opcode2 = op_CGFI
|
r1 = p.Reg
|
||||||
case ACMPUBEQ, ACMPUBGE, ACMPUBGT, ACMPUBLE, ACMPUBLT, ACMPUBNE:
|
}
|
||||||
opcode = op_CLGIJ
|
m3 := c.branchMask(p)
|
||||||
opcode2 = op_CLGFI
|
|
||||||
|
var opcode uint32
|
||||||
|
switch p.As {
|
||||||
|
case ACIJ:
|
||||||
|
opcode = op_CIJ
|
||||||
|
case ACGIJ, ACMPBEQ, ACMPBGE, ACMPBGT, ACMPBLE, ACMPBLT, ACMPBNE:
|
||||||
|
opcode = op_CGIJ
|
||||||
|
case ACLIJ:
|
||||||
|
opcode = op_CLIJ
|
||||||
|
case ACLGIJ, ACMPUBEQ, ACMPUBGE, ACMPUBGT, ACMPUBLE, ACMPUBLT, ACMPUBNE:
|
||||||
|
opcode = op_CLGIJ
|
||||||
}
|
}
|
||||||
mask := c.branchMask(p)
|
|
||||||
if int32(int16(v)) != v {
|
if int32(int16(v)) != v {
|
||||||
zRIL(_a, opcode2, uint32(p.From.Reg), uint32(c.regoff(p.GetFrom3())), asm)
|
// The branch is too far for one instruction so crack
|
||||||
zRIL(_c, op_BRCL, mask, uint32(v-sizeRIL/2), asm)
|
// `CMPBEQ x, $0, target` into:
|
||||||
|
//
|
||||||
|
// CMPBNE x, $0, 2(PC)
|
||||||
|
// BR target
|
||||||
|
//
|
||||||
|
// Note that the instruction sequence MUST NOT clobber
|
||||||
|
// the condition code.
|
||||||
|
m3 ^= 0xe // invert 3-bit mask
|
||||||
|
zRIE(_c, opcode, uint32(r1), m3, uint32(sizeRIE+sizeRIL)/2, 0, 0, 0, uint32(i2), asm)
|
||||||
|
zRIL(_c, op_BRCL, 0xf, uint32(v-sizeRIE/2), asm)
|
||||||
} else {
|
} else {
|
||||||
zRIE(_c, opcode, uint32(p.From.Reg), mask, uint32(v), 0, 0, 0, uint32(c.regoff(p.GetFrom3())), asm)
|
zRIE(_c, opcode, uint32(r1), m3, uint32(v), 0, 0, 0, uint32(i2), asm)
|
||||||
}
|
}
|
||||||
|
|
||||||
case 91: // test under mask (immediate)
|
case 91: // test under mask (immediate)
|
||||||
|
@ -249,6 +249,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
fallthrough
|
fallthrough
|
||||||
|
|
||||||
case ABC,
|
case ABC,
|
||||||
|
ABRC,
|
||||||
ABEQ,
|
ABEQ,
|
||||||
ABGE,
|
ABGE,
|
||||||
ABGT,
|
ABGT,
|
||||||
@ -260,6 +261,14 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
ABR,
|
ABR,
|
||||||
ABVC,
|
ABVC,
|
||||||
ABVS,
|
ABVS,
|
||||||
|
ACRJ,
|
||||||
|
ACGRJ,
|
||||||
|
ACLRJ,
|
||||||
|
ACLGRJ,
|
||||||
|
ACIJ,
|
||||||
|
ACGIJ,
|
||||||
|
ACLIJ,
|
||||||
|
ACLGIJ,
|
||||||
ACMPBEQ,
|
ACMPBEQ,
|
||||||
ACMPBGE,
|
ACMPBGE,
|
||||||
ACMPBGT,
|
ACMPBGT,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user