s390x: Fix bitwise operations (#4146)
Current codegen had a number of logic errors confusing NAND with AND WITH COMPLEMENT, and NOR with OR WITH COMPLEMENT. Add support for the missing z15 instructions and fix logic.
This commit is contained in:
@@ -996,12 +996,16 @@ impl MachInstEmit for Inst {
|
||||
ALUOp::Orr64 => (0xb9e6, true), // OGRK
|
||||
ALUOp::Xor32 => (0xb9f7, true), // XRK
|
||||
ALUOp::Xor64 => (0xb9e7, true), // XGRK
|
||||
ALUOp::AndNot32 => (0xb974, false), // NNRK
|
||||
ALUOp::AndNot64 => (0xb964, false), // NNGRK
|
||||
ALUOp::OrrNot32 => (0xb976, false), // NORK
|
||||
ALUOp::OrrNot64 => (0xb966, false), // NOGRK
|
||||
ALUOp::XorNot32 => (0xb977, false), // NXRK
|
||||
ALUOp::XorNot64 => (0xb967, false), // NXGRK
|
||||
ALUOp::NotAnd32 => (0xb974, false), // NNRK
|
||||
ALUOp::NotAnd64 => (0xb964, false), // NNGRK
|
||||
ALUOp::NotOrr32 => (0xb976, false), // NORK
|
||||
ALUOp::NotOrr64 => (0xb966, false), // NOGRK
|
||||
ALUOp::NotXor32 => (0xb977, false), // NXRK
|
||||
ALUOp::NotXor64 => (0xb967, false), // NXGRK
|
||||
ALUOp::AndNot32 => (0xb9f5, false), // NCRK
|
||||
ALUOp::AndNot64 => (0xb9e5, false), // NCGRK
|
||||
ALUOp::OrrNot32 => (0xb975, false), // OCRK
|
||||
ALUOp::OrrNot64 => (0xb965, false), // OCGRK
|
||||
_ => unreachable!(),
|
||||
};
|
||||
if have_rr && rd.to_reg() == rn {
|
||||
|
||||
@@ -178,7 +178,7 @@ fn test_s390x_binemit() {
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRR {
|
||||
alu_op: ALUOp::AndNot32,
|
||||
alu_op: ALUOp::NotAnd32,
|
||||
rd: writable_gpr(1),
|
||||
rn: gpr(2),
|
||||
rm: gpr(3),
|
||||
@@ -188,7 +188,7 @@ fn test_s390x_binemit() {
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRR {
|
||||
alu_op: ALUOp::AndNot64,
|
||||
alu_op: ALUOp::NotAnd64,
|
||||
rd: writable_gpr(4),
|
||||
rn: gpr(5),
|
||||
rm: gpr(6),
|
||||
@@ -198,7 +198,7 @@ fn test_s390x_binemit() {
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRR {
|
||||
alu_op: ALUOp::OrrNot32,
|
||||
alu_op: ALUOp::NotOrr32,
|
||||
rd: writable_gpr(1),
|
||||
rn: gpr(2),
|
||||
rm: gpr(3),
|
||||
@@ -208,7 +208,7 @@ fn test_s390x_binemit() {
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRR {
|
||||
alu_op: ALUOp::OrrNot64,
|
||||
alu_op: ALUOp::NotOrr64,
|
||||
rd: writable_gpr(4),
|
||||
rn: gpr(5),
|
||||
rm: gpr(6),
|
||||
@@ -218,7 +218,7 @@ fn test_s390x_binemit() {
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRR {
|
||||
alu_op: ALUOp::XorNot32,
|
||||
alu_op: ALUOp::NotXor32,
|
||||
rd: writable_gpr(1),
|
||||
rn: gpr(2),
|
||||
rm: gpr(3),
|
||||
@@ -228,7 +228,7 @@ fn test_s390x_binemit() {
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRR {
|
||||
alu_op: ALUOp::XorNot64,
|
||||
alu_op: ALUOp::NotXor64,
|
||||
rd: writable_gpr(4),
|
||||
rn: gpr(5),
|
||||
rm: gpr(6),
|
||||
@@ -236,6 +236,46 @@ fn test_s390x_binemit() {
|
||||
"B9676045",
|
||||
"nxgrk %r4, %r5, %r6",
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRR {
|
||||
alu_op: ALUOp::AndNot32,
|
||||
rd: writable_gpr(1),
|
||||
rn: gpr(2),
|
||||
rm: gpr(3),
|
||||
},
|
||||
"B9F53012",
|
||||
"ncrk %r1, %r2, %r3",
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRR {
|
||||
alu_op: ALUOp::AndNot64,
|
||||
rd: writable_gpr(4),
|
||||
rn: gpr(5),
|
||||
rm: gpr(6),
|
||||
},
|
||||
"B9E56045",
|
||||
"ncgrk %r4, %r5, %r6",
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRR {
|
||||
alu_op: ALUOp::OrrNot32,
|
||||
rd: writable_gpr(1),
|
||||
rn: gpr(2),
|
||||
rm: gpr(3),
|
||||
},
|
||||
"B9753012",
|
||||
"ocrk %r1, %r2, %r3",
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRR {
|
||||
alu_op: ALUOp::OrrNot64,
|
||||
rd: writable_gpr(4),
|
||||
rn: gpr(5),
|
||||
rm: gpr(6),
|
||||
},
|
||||
"B9656045",
|
||||
"ocgrk %r4, %r5, %r6",
|
||||
));
|
||||
|
||||
insns.push((
|
||||
Inst::AluRRSImm16 {
|
||||
|
||||
@@ -193,9 +193,11 @@ impl Inst {
|
||||
|
||||
// These depend on the opcode
|
||||
Inst::AluRRR { alu_op, .. } => match alu_op {
|
||||
ALUOp::NotAnd32 | ALUOp::NotAnd64 => InstructionSet::MIE2,
|
||||
ALUOp::NotOrr32 | ALUOp::NotOrr64 => InstructionSet::MIE2,
|
||||
ALUOp::NotXor32 | ALUOp::NotXor64 => InstructionSet::MIE2,
|
||||
ALUOp::AndNot32 | ALUOp::AndNot64 => InstructionSet::MIE2,
|
||||
ALUOp::OrrNot32 | ALUOp::OrrNot64 => InstructionSet::MIE2,
|
||||
ALUOp::XorNot32 | ALUOp::XorNot64 => InstructionSet::MIE2,
|
||||
_ => InstructionSet::Base,
|
||||
},
|
||||
Inst::UnaryRR { op, .. } => match op {
|
||||
@@ -933,12 +935,16 @@ impl Inst {
|
||||
ALUOp::Orr64 => ("ogrk", true),
|
||||
ALUOp::Xor32 => ("xrk", true),
|
||||
ALUOp::Xor64 => ("xgrk", true),
|
||||
ALUOp::AndNot32 => ("nnrk", false),
|
||||
ALUOp::AndNot64 => ("nngrk", false),
|
||||
ALUOp::OrrNot32 => ("nork", false),
|
||||
ALUOp::OrrNot64 => ("nogrk", false),
|
||||
ALUOp::XorNot32 => ("nxrk", false),
|
||||
ALUOp::XorNot64 => ("nxgrk", false),
|
||||
ALUOp::NotAnd32 => ("nnrk", false),
|
||||
ALUOp::NotAnd64 => ("nngrk", false),
|
||||
ALUOp::NotOrr32 => ("nork", false),
|
||||
ALUOp::NotOrr64 => ("nogrk", false),
|
||||
ALUOp::NotXor32 => ("nxrk", false),
|
||||
ALUOp::NotXor64 => ("nxgrk", false),
|
||||
ALUOp::AndNot32 => ("ncrk", false),
|
||||
ALUOp::AndNot64 => ("ncgrk", false),
|
||||
ALUOp::OrrNot32 => ("ocrk", false),
|
||||
ALUOp::OrrNot64 => ("ocgrk", false),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
if have_rr && rd.to_reg() == rn {
|
||||
|
||||
Reference in New Issue
Block a user