From 901e484fdaba2be4eacbaee4fc9e05df8d5b783b Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Mon, 4 Dec 2023 17:03:00 +0100 Subject: [PATCH] [SystemZ] Handle index-only addresses in (dis)assembler Most addresses in SystemZ instructions take two registers, an index register and a base register. However, either of those can be omitted. If there is just a single register, this usually is taken as the base register - however, there are certain rare cases where you specifically want to use an index register but no base register. This is currently not handled consistently by the assembler / disassembler. Fix this by - always emitting a dummy 0 as base register for index- only addresses - correctly handle dummy 0 as indicating no base register when parsing an address This is compatible with current GNU binutils behavior. --- .../SystemZ/AsmParser/SystemZAsmParser.cpp | 14 +++++----- .../MCTargetDesc/SystemZInstPrinter.cpp | 5 ++-- llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 4 +-- .../MC/Disassembler/SystemZ/insns-z13.txt | 8 +++--- llvm/test/MC/SystemZ/fixups.s | 4 +-- llvm/test/MC/SystemZ/insn-good-z13.s | 12 ++++---- llvm/test/MC/SystemZ/insn-good.s | 28 +++++++++++++++++-- 7 files changed, 49 insertions(+), 26 deletions(-) diff --git a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp index 2249b54161c2..c16004e2fea2 100644 --- a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp +++ b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp @@ -1123,7 +1123,7 @@ ParseStatus SystemZAsmParser::parseAddress(OperandVector &Operands, if (HaveReg1) { if (parseAddressRegister(Reg1)) return ParseStatus::Failure; - Base = Regs[Reg1.Num]; + Base = Reg1.Num == 0 ? 0 : Regs[Reg1.Num]; } // There must be no Reg2. if (HaveReg2) @@ -1137,15 +1137,15 @@ ParseStatus SystemZAsmParser::parseAddress(OperandVector &Operands, // If the are two registers, the first one is the index and the // second is the base. if (HaveReg2) - Index = Regs[Reg1.Num]; + Index = Reg1.Num == 0 ? 0 : Regs[Reg1.Num]; else - Base = Regs[Reg1.Num]; + Base = Reg1.Num == 0 ? 0 : Regs[Reg1.Num]; } // If we have Reg2, it must be an address register. if (HaveReg2) { if (parseAddressRegister(Reg2)) return ParseStatus::Failure; - Base = Regs[Reg2.Num]; + Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num]; } break; case BDLMem: @@ -1153,7 +1153,7 @@ ParseStatus SystemZAsmParser::parseAddress(OperandVector &Operands, if (HaveReg2) { if (parseAddressRegister(Reg2)) return ParseStatus::Failure; - Base = Regs[Reg2.Num]; + Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num]; } // We cannot support base+index addressing. if (HaveReg1 && HaveReg2) @@ -1171,7 +1171,7 @@ ParseStatus SystemZAsmParser::parseAddress(OperandVector &Operands, if (HaveReg2) { if (parseAddressRegister(Reg2)) return ParseStatus::Failure; - Base = Regs[Reg2.Num]; + Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num]; } break; case BDVMem: @@ -1183,7 +1183,7 @@ ParseStatus SystemZAsmParser::parseAddress(OperandVector &Operands, if (HaveReg2) { if (parseAddressRegister(Reg2)) return ParseStatus::Failure; - Base = Regs[Reg2.Num]; + Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num]; } break; } diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.cpp index b622e7f3b27b..fa534fadc323 100644 --- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.cpp +++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.cpp @@ -32,11 +32,12 @@ void SystemZInstPrinter::printAddress(const MCAsmInfo *MAI, MCRegister Base, O << '('; if (Index) { printFormattedRegName(MAI, Index, O); - if (Base) - O << ','; + O << ','; } if (Base) printFormattedRegName(MAI, Base, O); + else + O << '0'; O << ')'; } } diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp index df6f52449ac3..3186002c57d9 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -353,9 +353,9 @@ void SystemZAsmPrinter::emitInstruction(const MachineInstr *MI) { } EmitToStreamer(*OutStreamer, MCInstBuilder(Op) .addReg(TargetReg) - .addReg(IndexReg) + .addReg(ADAReg) .addImm(Disp) - .addReg(ADAReg)); + .addReg(IndexReg)); return; } diff --git a/llvm/test/MC/Disassembler/SystemZ/insns-z13.txt b/llvm/test/MC/Disassembler/SystemZ/insns-z13.txt index 3264db8fc764..4ba8184a8a58 100644 --- a/llvm/test/MC/Disassembler/SystemZ/insns-z13.txt +++ b/llvm/test/MC/Disassembler/SystemZ/insns-z13.txt @@ -2150,7 +2150,7 @@ # CHECK: vone %v31 0xe7 0xf0 0xff 0xff 0x08 0x44 -# CHECK: vgef %v0, 0(%v0), 0 +# CHECK: vgef %v0, 0(%v0,0), 0 0xe7 0x00 0x00 0x00 0x00 0x13 # CHECK: vgef %v10, 1000(%v19,%r7), 2 @@ -2159,7 +2159,7 @@ # CHECK: vgef %v31, 4095(%v31,%r15), 3 0xe7 0xff 0xff 0xff 0x3c 0x13 -# CHECK: vgeg %v0, 0(%v0), 0 +# CHECK: vgeg %v0, 0(%v0,0), 0 0xe7 0x00 0x00 0x00 0x00 0x12 # CHECK: vgeg %v10, 1000(%v19,%r7), 1 @@ -3959,7 +3959,7 @@ # CHECK: vscbiq %v31, %v31, %v31 0xe7 0xff 0xf0 0x00 0x4e 0xf5 -# CHECK: vscef %v0, 0(%v0), 0 +# CHECK: vscef %v0, 0(%v0,0), 0 0xe7 0x00 0x00 0x00 0x00 0x1b # CHECK: vscef %v10, 1000(%v19,%r7), 2 @@ -3968,7 +3968,7 @@ # CHECK: vscef %v31, 4095(%v31,%r15), 3 0xe7 0xff 0xff 0xff 0x3c 0x1b -# CHECK: vsceg %v0, 0(%v0), 0 +# CHECK: vsceg %v0, 0(%v0,0), 0 0xe7 0x00 0x00 0x00 0x00 0x1a # CHECK: vsceg %v10, 1000(%v19,%r7), 1 diff --git a/llvm/test/MC/SystemZ/fixups.s b/llvm/test/MC/SystemZ/fixups.s index 3c2138e9e621..ad0b1f18cdcf 100644 --- a/llvm/test/MC/SystemZ/fixups.s +++ b/llvm/test/MC/SystemZ/fixups.s @@ -291,10 +291,10 @@ vgeg %v0, src(%v0,%r1), 0 ## Fixup for second operand only -# CHECK: mvc 32(8,%r0), src # encoding: [0xd2,0x07,0x00,0x20,0b0000AAAA,A] +# CHECK: mvc 32(8,%r1), src # encoding: [0xd2,0x07,0x10,0x20,0b0000AAAA,A] # CHECK-NEXT: # fixup A - offset: 4, value: src, kind: FK_390_U12Imm .align 16 - mvc 32(8,%r0),src + mvc 32(8,%r1),src ##U8 # CHECK: cli 0(%r1), src # encoding: [0x95,A,0x10,0x00] diff --git a/llvm/test/MC/SystemZ/insn-good-z13.s b/llvm/test/MC/SystemZ/insn-good-z13.s index 4e3ba50ad7f9..37d80c34289b 100644 --- a/llvm/test/MC/SystemZ/insn-good-z13.s +++ b/llvm/test/MC/SystemZ/insn-good-z13.s @@ -2879,7 +2879,7 @@ vgbm %v31, 0 vgbm %v17, 0x1234 -#CHECK: vgef %v0, 0(%v0), 0 # encoding: [0xe7,0x00,0x00,0x00,0x00,0x13] +#CHECK: vgef %v0, 0(%v0,0), 0 # encoding: [0xe7,0x00,0x00,0x00,0x00,0x13] #CHECK: vgef %v0, 0(%v0,%r1), 0 # encoding: [0xe7,0x00,0x10,0x00,0x00,0x13] #CHECK: vgef %v0, 0(%v0,%r1), 3 # encoding: [0xe7,0x00,0x10,0x00,0x30,0x13] #CHECK: vgef %v0, 0(%v0,%r15), 0 # encoding: [0xe7,0x00,0xf0,0x00,0x00,0x13] @@ -2893,7 +2893,7 @@ #CHECK: vgef %v0, 0(%v0,%r1), 3 # encoding: [0xe7,0x00,0x10,0x00,0x30,0x13] #CHECK: vgef %v0, 0(%v0,%r15), 0 # encoding: [0xe7,0x00,0xf0,0x00,0x00,0x13] #CHECK: vgef %v0, 0(%v15,%r1), 0 # encoding: [0xe7,0x0f,0x10,0x00,0x00,0x13] -#CHECK: vgef %v0, 0(%v0), 0 # encoding: [0xe7,0x00,0x00,0x00,0x00,0x13] +#CHECK: vgef %v0, 0(%v0,0), 0 # encoding: [0xe7,0x00,0x00,0x00,0x00,0x13] #CHECK: vgef %v0, 0(%v0,%r1), 0 # encoding: [0xe7,0x00,0x10,0x00,0x00,0x13] #CHECK: vgef %v0, 0(%v0,%r1), 3 # encoding: [0xe7,0x00,0x10,0x00,0x30,0x13] #CHECK: vgef %v0, 0(%v0,%r15), 0 # encoding: [0xe7,0x00,0xf0,0x00,0x00,0x13] @@ -2929,7 +2929,7 @@ vgef 31, 0(0,1), 0 vgef 10, 1000(19,7), 1 -#CHECK: vgeg %v0, 0(%v0), 0 # encoding: [0xe7,0x00,0x00,0x00,0x00,0x12] +#CHECK: vgeg %v0, 0(%v0,0), 0 # encoding: [0xe7,0x00,0x00,0x00,0x00,0x12] #CHECK: vgeg %v0, 0(%v0,%r1), 0 # encoding: [0xe7,0x00,0x10,0x00,0x00,0x12] #CHECK: vgeg %v0, 0(%v0,%r1), 1 # encoding: [0xe7,0x00,0x10,0x00,0x10,0x12] #CHECK: vgeg %v0, 0(%v0,%r15), 0 # encoding: [0xe7,0x00,0xf0,0x00,0x00,0x12] @@ -2943,7 +2943,7 @@ #CHECK: vgeg %v0, 0(%v0,%r1), 1 # encoding: [0xe7,0x00,0x10,0x00,0x10,0x12] #CHECK: vgeg %v0, 0(%v0,%r15), 0 # encoding: [0xe7,0x00,0xf0,0x00,0x00,0x12] #CHECK: vgeg %v0, 0(%v15,%r1), 0 # encoding: [0xe7,0x0f,0x10,0x00,0x00,0x12] -#CHECK: vgeg %v0, 0(%v0), 0 # encoding: [0xe7,0x00,0x00,0x00,0x00,0x12] +#CHECK: vgeg %v0, 0(%v0,0), 0 # encoding: [0xe7,0x00,0x00,0x00,0x00,0x12] #CHECK: vgeg %v0, 0(%v0,%r1), 0 # encoding: [0xe7,0x00,0x10,0x00,0x00,0x12] #CHECK: vgeg %v0, 0(%v0,%r1), 1 # encoding: [0xe7,0x00,0x10,0x00,0x10,0x12] #CHECK: vgeg %v0, 0(%v0,%r15), 0 # encoding: [0xe7,0x00,0xf0,0x00,0x00,0x12] @@ -5911,7 +5911,7 @@ vscbiq %v31, %v0, %v0 vscbiq %v18, %v3, %v20 -#CHECK: vscef %v0, 0(%v0), 0 # encoding: [0xe7,0x00,0x00,0x00,0x00,0x1b] +#CHECK: vscef %v0, 0(%v0,0), 0 # encoding: [0xe7,0x00,0x00,0x00,0x00,0x1b] #CHECK: vscef %v0, 0(%v0,%r1), 0 # encoding: [0xe7,0x00,0x10,0x00,0x00,0x1b] #CHECK: vscef %v0, 0(%v0,%r1), 3 # encoding: [0xe7,0x00,0x10,0x00,0x30,0x1b] #CHECK: vscef %v0, 0(%v0,%r15), 0 # encoding: [0xe7,0x00,0xf0,0x00,0x00,0x1b] @@ -5933,7 +5933,7 @@ vscef %v31, 0(%v0,%r1), 0 vscef %v10, 1000(%v19,%r7), 1 -#CHECK: vsceg %v0, 0(%v0), 0 # encoding: [0xe7,0x00,0x00,0x00,0x00,0x1a] +#CHECK: vsceg %v0, 0(%v0,0), 0 # encoding: [0xe7,0x00,0x00,0x00,0x00,0x1a] #CHECK: vsceg %v0, 0(%v0,%r1), 0 # encoding: [0xe7,0x00,0x10,0x00,0x00,0x1a] #CHECK: vsceg %v0, 0(%v0,%r1), 1 # encoding: [0xe7,0x00,0x10,0x00,0x10,0x1a] #CHECK: vsceg %v0, 0(%v0,%r15), 0 # encoding: [0xe7,0x00,0xf0,0x00,0x00,0x1a] diff --git a/llvm/test/MC/SystemZ/insn-good.s b/llvm/test/MC/SystemZ/insn-good.s index 34961b3d3f77..91120f7f97aa 100644 --- a/llvm/test/MC/SystemZ/insn-good.s +++ b/llvm/test/MC/SystemZ/insn-good.s @@ -8757,12 +8757,22 @@ #CHECK: l %r0, 0 # encoding: [0x58,0x00,0x00,0x00] #CHECK: l %r0, 4095 # encoding: [0x58,0x00,0x0f,0xff] -#CHECK: l %r0, 0(%r0) # encoding: [0x58,0x00,0x00,0x00] +#CHECK: l %r0, 0 # encoding: [0x58,0x00,0x00,0x00] #CHECK: l %r0, 0(%r1) # encoding: [0x58,0x00,0x10,0x00] #CHECK: l %r0, 0(%r15) # encoding: [0x58,0x00,0xf0,0x00] -#CHECK: l %r0, 4095(%r0,%r15) # encoding: [0x58,0x00,0xff,0xff] +#CHECK: l %r0, 0(%r1) # encoding: [0x58,0x00,0x10,0x00] +#CHECK: l %r0, 0(%r15) # encoding: [0x58,0x00,0xf0,0x00] +#CHECK: l %r0, 0(%r1) # encoding: [0x58,0x00,0x10,0x00] +#CHECK: l %r0, 0(%r15) # encoding: [0x58,0x00,0xf0,0x00] +#CHECK: l %r0, 0(%r1) # encoding: [0x58,0x00,0x10,0x00] +#CHECK: l %r0, 0(%r15) # encoding: [0x58,0x00,0xf0,0x00] +#CHECK: l %r0, 0(%r1,0) # encoding: [0x58,0x01,0x00,0x00] +#CHECK: l %r0, 0(%r15,0) # encoding: [0x58,0x0f,0x00,0x00] +#CHECK: l %r0, 0(%r1,0) # encoding: [0x58,0x01,0x00,0x00] +#CHECK: l %r0, 0(%r15,0) # encoding: [0x58,0x0f,0x00,0x00] +#CHECK: l %r0, 4095(%r15) # encoding: [0x58,0x00,0xff,0xff] #CHECK: l %r0, 4095(%r1,%r15) # encoding: [0x58,0x01,0xff,0xff] -#CHECK: l %r0, 4095(%r15,%r0) # encoding: [0x58,0x0f,0x0f,0xff] +#CHECK: l %r0, 4095(%r15,0) # encoding: [0x58,0x0f,0x0f,0xff] #CHECK: l %r0, 4095(%r15,%r1) # encoding: [0x58,0x0f,0x1f,0xff] #CHECK: l %r15, 0 # encoding: [0x58,0xf0,0x00,0x00] @@ -8771,6 +8781,18 @@ l %r0, 0(%r0) l %r0, 0(%r1) l %r0, 0(%r15) + l %r0, 0(,%r1) + l %r0, 0(,%r15) + l %r0, 0(0,%r1) + l %r0, 0(0,%r15) + l %r0, 0(%r0,%r1) + l %r0, 0(%r0,%r15) + l %r0, 0(0,%r1) + l %r0, 0(0,%r15) + l %r0, 0(%r1,0) + l %r0, 0(%r15,0) + l %r0, 0(%r1,%r0) + l %r0, 0(%r15,%r0) l %r0, 4095(%r0,%r15) l %r0, 4095(%r1,%r15) l %r0, 4095(%r15,%r0)