NEGW R1, R2 // b9130021
FLOGR R2, R2 // b9830022
+ AND R1, R2 // b9800021
+ AND R1, R2, R3 // b9e42031
+ AND $-2, R1 // a517fffe
+ AND $-65536, R1 // c01bffff0000
+ AND $1, R1 // c0a100000001b980001a
+ ANDW R1, R2 // 1421
+ ANDW R1, R2, R3 // b9f42031
+ ANDW $1, R1 // c01b00000001
+ ANDW $131071, R1 // a5160001
+ ANDW $65536, R1 // c01b00010000
+ ANDW $-2, R1 // a517fffe
+ OR R1, R2 // b9810021
+ OR R1, R2, R3 // b9e62031
+ OR $1, R1 // a51b0001
+ OR $131071, R1 // c01d0001ffff
+ OR $65536, R1 // c01d00010000
+ OR $-2, R1 // c0a1fffffffeb981001a
+ ORW R1, R2 // 1621
+ ORW R1, R2, R3 // b9f62031
+ ORW $1, R1 // a51b0001
+ ORW $131071, R1 // c01d0001ffff
+ ORW $65536, R1 // a51a0001
+ ORW $-2, R1 // c01dfffffffe
+ XOR R1, R2 // b9820021
+ XOR R1, R2, R3 // b9e72031
+ XOR $1, R1 // c01700000001
+ XOR $131071, R1 // c0170001ffff
+ XOR $65536, R1 // c01700010000
+ XOR $-2, R1 // c0a1fffffffeb982001a
+ XORW R1, R2 // 1721
+ XORW R1, R2, R3 // b9f72031
+ XORW $1, R1 // c01700000001
+ XORW $131071, R1 // c0170001ffff
+ XORW $65536, R1 // c01700010000
+ XORW $-2, R1 // c017fffffffe
+
LAA R1, R2, 524287(R3) // eb213fff7ff8
LAAG R4, R5, -524288(R6) // eb54600080e8
LAAL R7, R8, 8192(R9) // eb87900002fa
s390x.ANEG & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite},
s390x.ANEGW & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RegRead | gc.RightWrite},
s390x.AAND & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite},
+ s390x.AANDW & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RegRead | gc.RightWrite},
s390x.AOR & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite},
+ s390x.AORW & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RegRead | gc.RightWrite},
s390x.AXOR & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite},
+ s390x.AXORW & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RegRead | gc.RightWrite},
s390x.AMULLD & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite},
s390x.AMULLW & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RegRead | gc.RightWrite},
s390x.AMULHD & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite},
{name: "MODDU", argLength: 2, reg: gp21, asm: "MODDU", resultInArg0: true, clobberFlags: true}, // arg0 % arg1
{name: "MODWU", argLength: 2, reg: gp21, asm: "MODWU", resultInArg0: true, clobberFlags: true}, // arg0 % arg1
- {name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true, clobberFlags: true}, // arg0 & arg1
- {name: "ANDW", argLength: 2, reg: gp21, asm: "AND", commutative: true, clobberFlags: true}, // arg0 & arg1
- {name: "ANDconst", argLength: 1, reg: gp11, asm: "AND", aux: "Int64", resultInArg0: true, clobberFlags: true}, // arg0 & auxint
- {name: "ANDWconst", argLength: 1, reg: gp11, asm: "AND", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 & auxint
-
- {name: "OR", argLength: 2, reg: gp21, asm: "OR", commutative: true, clobberFlags: true}, // arg0 | arg1
- {name: "ORW", argLength: 2, reg: gp21, asm: "OR", commutative: true, clobberFlags: true}, // arg0 | arg1
- {name: "ORconst", argLength: 1, reg: gp11, asm: "OR", aux: "Int64", resultInArg0: true, clobberFlags: true}, // arg0 | auxint
- {name: "ORWconst", argLength: 1, reg: gp11, asm: "OR", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 | auxint
-
- {name: "XOR", argLength: 2, reg: gp21, asm: "XOR", commutative: true, clobberFlags: true}, // arg0 ^ arg1
- {name: "XORW", argLength: 2, reg: gp21, asm: "XOR", commutative: true, clobberFlags: true}, // arg0 ^ arg1
- {name: "XORconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int64", resultInArg0: true, clobberFlags: true}, // arg0 ^ auxint
- {name: "XORWconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 ^ auxint
+ {name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true, clobberFlags: true}, // arg0 & arg1
+ {name: "ANDW", argLength: 2, reg: gp21, asm: "ANDW", commutative: true, clobberFlags: true}, // arg0 & arg1
+ {name: "ANDconst", argLength: 1, reg: gp11, asm: "AND", aux: "Int64", resultInArg0: true, clobberFlags: true}, // arg0 & auxint
+ {name: "ANDWconst", argLength: 1, reg: gp11, asm: "ANDW", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 & auxint
+
+ {name: "OR", argLength: 2, reg: gp21, asm: "OR", commutative: true, clobberFlags: true}, // arg0 | arg1
+ {name: "ORW", argLength: 2, reg: gp21, asm: "ORW", commutative: true, clobberFlags: true}, // arg0 | arg1
+ {name: "ORconst", argLength: 1, reg: gp11, asm: "OR", aux: "Int64", resultInArg0: true, clobberFlags: true}, // arg0 | auxint
+ {name: "ORWconst", argLength: 1, reg: gp11, asm: "ORW", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 | auxint
+
+ {name: "XOR", argLength: 2, reg: gp21, asm: "XOR", commutative: true, clobberFlags: true}, // arg0 ^ arg1
+ {name: "XORW", argLength: 2, reg: gp21, asm: "XORW", commutative: true, clobberFlags: true}, // arg0 ^ arg1
+ {name: "XORconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int64", resultInArg0: true, clobberFlags: true}, // arg0 ^ auxint
+ {name: "XORWconst", argLength: 1, reg: gp11, asm: "XORW", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 ^ auxint
{name: "CMP", argLength: 2, reg: gp2flags, asm: "CMP", typ: "Flags"}, // arg0 compare to arg1
{name: "CMPW", argLength: 2, reg: gp2flags, asm: "CMPW", typ: "Flags"}, // arg0 compare to arg1
argLen: 2,
commutative: true,
clobberFlags: true,
- asm: s390x.AAND,
+ asm: s390x.AANDW,
reg: regInfo{
inputs: []inputInfo{
{0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
argLen: 1,
resultInArg0: true,
clobberFlags: true,
- asm: s390x.AAND,
+ asm: s390x.AANDW,
reg: regInfo{
inputs: []inputInfo{
{0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
argLen: 2,
commutative: true,
clobberFlags: true,
- asm: s390x.AOR,
+ asm: s390x.AORW,
reg: regInfo{
inputs: []inputInfo{
{0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
argLen: 1,
resultInArg0: true,
clobberFlags: true,
- asm: s390x.AOR,
+ asm: s390x.AORW,
reg: regInfo{
inputs: []inputInfo{
{0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
argLen: 2,
commutative: true,
clobberFlags: true,
- asm: s390x.AXOR,
+ asm: s390x.AXORW,
reg: regInfo{
inputs: []inputInfo{
{0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
argLen: 1,
resultInArg0: true,
clobberFlags: true,
- asm: s390x.AXOR,
+ asm: s390x.AXORW,
reg: regInfo{
inputs: []inputInfo{
{0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
// integer bitwise
AAND
- AANDN
- ANAND
- ANOR
+ AANDW
AOR
- AORN
+ AORW
AXOR
+ AXORW
ASLW
ASLD
ASRW
"MOVDNE",
"FLOGR",
"AND",
- "ANDN",
- "NAND",
- "NOR",
+ "ANDW",
"OR",
- "ORN",
+ "ORW",
"XOR",
+ "XORW",
"SLW",
"SLD",
"SRW",
Optab{AAND, C_REG, C_NONE, C_NONE, C_REG, 6, 0},
Optab{AAND, C_LCON, C_NONE, C_NONE, C_REG, 23, 0},
Optab{AAND, C_LCON, C_REG, C_NONE, C_REG, 23, 0},
- Optab{AOR, C_REG, C_REG, C_NONE, C_REG, 6, 0},
- Optab{AOR, C_REG, C_NONE, C_NONE, C_REG, 6, 0},
- Optab{AOR, C_LCON, C_NONE, C_NONE, C_REG, 23, 0},
- Optab{AOR, C_LCON, C_REG, C_NONE, C_REG, 23, 0},
+ Optab{AANDW, C_REG, C_REG, C_NONE, C_REG, 6, 0},
+ Optab{AANDW, C_REG, C_NONE, C_NONE, C_REG, 6, 0},
+ Optab{AANDW, C_LCON, C_NONE, C_NONE, C_REG, 24, 0},
Optab{ASLD, C_REG, C_NONE, C_NONE, C_REG, 7, 0},
Optab{ASLD, C_REG, C_REG, C_NONE, C_REG, 7, 0},
Optab{ASLD, C_SCON, C_REG, C_NONE, C_REG, 7, 0},
ctxt.Cursym = cursym
ctxt.Autosize = int32(p.To.Offset)
- if oprange[AANDN&obj.AMask] == nil {
+ if oprange[AORW&obj.AMask] == nil {
buildop(ctxt)
}
opset(ASTMY, r)
case ALMG:
opset(ALMY, r)
- case AAND:
- opset(AANDN, r)
- opset(ANAND, r)
- opset(ANOR, r)
- opset(AORN, r)
case AADDME:
opset(AADDZE, r)
opset(ASUBME, r)
case AFCMPO:
opset(AFCMPU, r)
opset(ACEBR, r)
- case AOR:
+ case AAND:
+ opset(AOR, r)
opset(AXOR, r)
+ case AANDW:
+ opset(AORW, r)
+ opset(AXORW, r)
case ASLD:
opset(ASRD, r)
opset(ASLW, r)
zI(op_SVC, 0, asm)
case 6: // logical op reg [reg] reg
- if p.To.Reg == 0 {
- ctxt.Diag("literal operation on R0\n%v", p)
- }
-
+ var oprr, oprre, oprrf uint32
switch p.As {
- case AAND, AOR, AXOR:
- var opcode1, opcode2 uint32
- switch p.As {
- default:
- case AAND:
- opcode1 = op_NGR
- opcode2 = op_NGRK
- case AOR:
- opcode1 = op_OGR
- opcode2 = op_OGRK
- case AXOR:
- opcode1 = op_XGR
- opcode2 = op_XGRK
- }
-
- r := int(p.Reg)
- if r == 0 {
- zRRE(opcode1, uint32(p.To.Reg), uint32(p.From.Reg), asm)
- } else {
- zRRF(opcode2, uint32(r), 0, uint32(p.To.Reg), uint32(p.From.Reg), asm)
- }
-
- case AANDN, AORN:
- var opcode1, opcode2 uint32
- switch p.As {
- default:
- case AANDN:
- opcode1 = op_NGR
- opcode2 = op_NGRK
- case AORN:
- opcode1 = op_OGR
- opcode2 = op_OGRK
- }
-
- r := int(p.Reg)
- if r == 0 {
- zRRE(op_LCGR, uint32(p.To.Reg), uint32(p.To.Reg), asm)
- zRRE(opcode1, uint32(p.To.Reg), uint32(p.From.Reg), asm)
- } else {
- zRRE(op_LCGR, REGTMP, uint32(r), asm)
- zRRF(opcode2, REGTMP, 0, uint32(p.To.Reg), uint32(p.From.Reg), asm)
- }
-
- case ANAND, ANOR:
- var opcode1, opcode2 uint32
- switch p.As {
- default:
- case ANAND:
- opcode1 = op_NGR
- opcode2 = op_NGRK
- case ANOR:
- opcode1 = op_OGR
- opcode2 = op_OGRK
- }
-
- r := int(p.Reg)
- if r == 0 {
- zRRE(opcode1, uint32(p.To.Reg), uint32(p.From.Reg), asm)
+ case AAND:
+ oprre = op_NGR
+ oprrf = op_NGRK
+ case AANDW:
+ oprr = op_NR
+ oprrf = op_NRK
+ case AOR:
+ oprre = op_OGR
+ oprrf = op_OGRK
+ case AORW:
+ oprr = op_OR
+ oprrf = op_ORK
+ case AXOR:
+ oprre = op_XGR
+ oprrf = op_XGRK
+ case AXORW:
+ oprr = op_XR
+ oprrf = op_XRK
+ }
+ if p.Reg == 0 {
+ if oprr != 0 {
+ zRR(oprr, uint32(p.To.Reg), uint32(p.From.Reg), asm)
} else {
- zRRF(opcode2, uint32(r), 0, uint32(p.To.Reg), uint32(p.From.Reg), asm)
+ zRRE(oprre, uint32(p.To.Reg), uint32(p.From.Reg), asm)
}
-
- zRRE(op_LCGR, uint32(p.To.Reg), uint32(p.To.Reg), asm)
+ } else {
+ zRRF(oprrf, uint32(p.Reg), 0, uint32(p.To.Reg), uint32(p.From.Reg), asm)
}
case 7: // shift/rotate reg [reg] reg
zRIE(_d, oprie, uint32(p.To.Reg), uint32(r), uint32(v), 0, 0, 0, 0, asm)
}
- case 23: // logical op $constant [reg] reg
+ case 23: // 64-bit logical op $constant [reg] reg
+ // TODO(mundaym): remove the optional register and merge with case 24.
v := vregoff(ctxt, &p.From)
var opcode uint32
r := p.Reg
zRRF(opcode, uint32(r), 0, uint32(p.To.Reg), REGTMP, asm)
}
+ case 24: // 32-bit logical op $constant reg
+ v := vregoff(ctxt, &p.From)
+ switch p.As {
+ case AANDW:
+ if uint32(v&0xffff0000) == 0xffff0000 {
+ zRI(op_NILL, uint32(p.To.Reg), uint32(v), asm)
+ } else if uint32(v&0x0000ffff) == 0x0000ffff {
+ zRI(op_NILH, uint32(p.To.Reg), uint32(v)>>16, asm)
+ } else {
+ zRIL(_a, op_NILF, uint32(p.To.Reg), uint32(v), asm)
+ }
+ case AORW:
+ if uint32(v&0xffff0000) == 0 {
+ zRI(op_OILL, uint32(p.To.Reg), uint32(v), asm)
+ } else if uint32(v&0x0000ffff) == 0 {
+ zRI(op_OILH, uint32(p.To.Reg), uint32(v)>>16, asm)
+ } else {
+ zRIL(_a, op_OILF, uint32(p.To.Reg), uint32(v), asm)
+ }
+ case AXORW:
+ zRIL(_a, op_XILF, uint32(p.To.Reg), uint32(v), asm)
+ }
+
case 26: // MOVD $offset(base)(index), reg
v := regoff(ctxt, &p.From)
r := p.From.Reg