llvm.org GIT mirror llvm / 81058a8
Merging r367580: ------------------------------------------------------------------------ r367580 | atanasyan | 2019-08-01 18:04:29 +0200 (Thu, 01 Aug 2019) | 18 lines [mips] Fix lowering load/store instruction in PIC case If an operand of the `lw/sw` instructions is a symbol, these instructions incorrectly lowered using not-position-independent chain of commands. For PIC code we should use `lw/addiu` instructions with the `R_MIPS_GOT16` and `R_MIPS_LO16` relocations respectively. Instead of that LLVM generates position dependent code with the `R_MIPS_HI16` and `R_MIPS_LO16` relocations. This patch provides a fix for the bug by handling PIC case separately in the `MipsAsmParser::expandMemInst`. The main idea is to generate a chain of PIC instructions to load a symbol address into a register and then load the address content. The fix is not optimal and does not fix all PIC-related problems. This is a task for subsequent patches. Differential Revision: https://reviews.llvm.org/D65524 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_90@369663 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 1 year, 3 months ago
3 changed file(s) with 130 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
36243624 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg,
36253625 BaseReg, IDLoc, STI);
36263626 TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, LoOffset, IDLoc, STI);
3627 return;
3628 }
3629
3630 assert(OffsetOp.isExpr() && "expected expression operand kind");
3631 if (inPicMode()) {
3632 // FIXME:
3633 // a) Fix lw/sw $reg, symbol($reg) instruction expanding.
3634 // b) If expression includes offset (sym + number), do not
3635 // encode the offset into a relocation. Take it in account
3636 // in the last load/store instruction.
3637 // c) Check that immediates of R_MIPS_GOT16/R_MIPS_LO16 relocations
3638 // do not exceed 16-bit.
3639 // d) Use R_MIPS_GOT_PAGE/R_MIPS_GOT_OFST relocations instead
3640 // of R_MIPS_GOT_DISP in appropriate cases to reduce number
3641 // of GOT entries.
3642 expandLoadAddress(TmpReg, Mips::NoRegister, OffsetOp, !ABI.ArePtrs64bit(),
3643 IDLoc, Out, STI);
3644 TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, 0, IDLoc, STI);
36273645 } else {
3628 assert(OffsetOp.isExpr() && "expected expression operand kind");
36293646 const MCExpr *ExprOffset = OffsetOp.getExpr();
36303647 MCOperand LoOperand = MCOperand::createExpr(
36313648 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
4949 # CHECK-LE: lhu $4, 4($4)
5050
5151 # LW/SW and LDC1/SDC1 of symbol address, done by MipsAsmParser::expandMemInst():
52 # NON-PIC code
5253 .set noat
5354 lw $10, symbol($4)
5455 # CHECK-LE: lui $10, %hi(symbol) # encoding: [A,A,0x0a,0x3c]
103104 sdc1 $f0, symbol
104105 # CHECK-LE: lui $1, %hi(symbol)
105106 # CHECK-LE: sdc1 $f0, %lo(symbol)($1)
107
108 # PIC code
109 .option pic2
110 .set noat
111 lw $10, symbol($4)
112 # CHECK-LE: lw $10, %got(symbol)($gp) # encoding: [A,A,0x8a,0x8f]
113 # CHECK-LE: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
114 # CHECK-LE-FIXME: addu $10, $10, $4 # encoding: [0x21,0x50,0x44,0x01]
115 # CHECK-LE: lw $10, 0($10) # encoding: [0x00,0x00,0x4a,0x8d]
116 .set at
117 sw $10, symbol($9)
118 # CHECK-LE: lw $1, %got(symbol)($gp) # encoding: [A,A,0x81,0x8f]
119 # CHECK-LE: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
120 # CHECK-LE-FIXME: addu $1, $1, $9 # encoding: [0x21,0x08,0x29,0x00]
121 # CHECK-LE: sw $10, 0($1) # encoding: [0x00,0x00,0x2a,0xac]
122
123 lw $8, 1f+8
124 # CHECK-LE: lw $8, %got(($tmp0)+8)($gp) # encoding: [A,A,0x88,0x8f]
125 # CHECK-LE: # fixup A - offset: 0, value: %got(($tmp0)+8), kind: fixup_Mips_GOT
126 # CHECK-LE: addiu $8, $8, %lo(($tmp0)+8) # encoding: [A,A,0x08,0x25]
127 # CHECK-LE: # fixup A - offset: 0, value: %lo(($tmp0)+8), kind: fixup_Mips_LO16
128 # CHECK-LE: lw $8, 0($8) # encoding: [0x00,0x00,0x08,0x8d]
129 sw $8, 1f+8
130 # CHECK-LE: lw $1, %got(($tmp0)+8)($gp) # encoding: [A,A,0x81,0x8f]
131 # CHECK-LE: # fixup A - offset: 0, value: %got(($tmp0)+8), kind: fixup_Mips_GOT
132 # CHECK-LE: addiu $1, $1, %lo(($tmp0)+8) # encoding: [A,A,0x21,0x24]
133 # CHECK-LE: # fixup A - offset: 0, value: %lo(($tmp0)+8), kind: fixup_Mips_LO16
134 # CHECK-LE: sw $8, 0($1) # encoding: [0x00,0x00,0x28,0xac]
135
136 lw $10, 655483($4)
137 # CHECK-LE: lui $10, 10 # encoding: [0x0a,0x00,0x0a,0x3c]
138 # CHECK-LE: addu $10, $10, $4 # encoding: [0x21,0x50,0x44,0x01]
139 # CHECK-LE: lw $10, 123($10) # encoding: [0x7b,0x00,0x4a,0x8d]
140 sw $10, 123456($9)
141 # CHECK-LE: lui $1, 2 # encoding: [0x02,0x00,0x01,0x3c]
142 # CHECK-LE: addu $1, $1, $9 # encoding: [0x21,0x08,0x29,0x00]
143 # CHECK-LE: sw $10, -7616($1) # encoding: [0x40,0xe2,0x2a,0xac]
144
145 lw $8, symbol+8
146 # CHECK-LE: lw $8, %got(symbol+8)($gp) # encoding: [A,A,0x88,0x8f]
147 # CHECK-LE: # fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT
148 # CHECK-LE: addiu $8, $8, 8 # encoding: [0x08,0x00,0x08,0x25]
149 # CHECK-LE: lw $8, 0($8) # encoding: [0x00,0x00,0x08,0x8d]
150 sw $8, symbol+8
151 # CHECK-LE: lw $1, %got(symbol+8)($gp) # encoding: [A,A,0x81,0x8f]
152 # CHECK-LE: # fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT
153 # CHECK-LE: addiu $1, $1, 8 # encoding: [0x08,0x00,0x21,0x24]
154 # CHECK-LE: sw $8, 0($1) # encoding: [0x00,0x00,0x28,0xac]
155
156 ldc1 $f0, symbol
157 # CHECK-LE: lw $1, %got(symbol)($gp) # encoding: [A,A,0x81,0x8f]
158 # CHECK-LE: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
159 # CHECK-LE: ldc1 $f0, 0($1) # encoding: [0x00,0x00,0x20,0xd4]
160 sdc1 $f0, symbol
161 # CHECK-LE: lw $1, %got(symbol)($gp) # encoding: [A,A,0x81,0x8f]
162 # CHECK-LE: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
163 # CHECK-LE: sdc1 $f0, 0($1) # encoding: [0x00,0x00,0x20,0xf4]
164 .option pic0
106165
107166 # Test BNE with an immediate as the 2nd operand.
108167 bne $2, 0, 1332
465465 # CHECK-NEXT: dsll $4, $4, 16
466466 # CHECK-NEXT: daddu $4, $4, $3
467467 # CHECK-NEXT: lhu $4, -32764($4)
468
469 # LW/SW and LDC1/SDC1 of symbol address, done by MipsAsmParser::expandMemInst():
470 .option pic2
471 lw $10, symbol($4)
472 # CHECK: ld $10, %got_disp(symbol)($gp) # encoding: [A,A,0x8a,0xdf]
473 # CHECK: # fixup A - offset: 0, value: %got_disp(symbol), kind: fixup_Mips_GOT_DISP
474 # CHECK-FIXME: daddu $10, $10, $4 # encoding: [0x2d,0x50,0x44,0x01]
475 # CHECK: lw $10, 0($10) # encoding: [0x00,0x00,0x4a,0x8d]
476 sw $10, symbol($9)
477 # CHECK: ld $1, %got_disp(symbol)($gp) # encoding: [A,A,0x81,0xdf]
478 # CHECK: # fixup A - offset: 0, value: %got_disp(symbol), kind: fixup_Mips_GOT_DISP
479 # CHECK-FIXME: daddu $1, $1, $9 # encoding: [0x2d,0x08,0x29,0x00]
480 # CHECK: sw $10, 0($1) # encoding: [0x00,0x00,0x2a,0xac]
481
482 lw $8, sym+8
483 # CHECK: ld $8, %got_disp(sym)($gp) # encoding: [A,A,0x88,0xdf]
484 # CHECK: # fixup A - offset: 0, value: %got_disp(sym), kind: fixup_Mips_GOT_DISP
485 # CHECK: daddiu $8, $8, 8 # encoding: [0x08,0x00,0x08,0x65]
486 # CHECK: lw $8, 0($8) # encoding: [0x00,0x00,0x08,0x8d]
487 sw $8, sym+8
488 # CHECK: ld $1, %got_disp(sym)($gp) # encoding: [A,A,0x81,0xdf]
489 # CHECK: # fixup A - offset: 0, value: %got_disp(sym), kind: fixup_Mips_GOT_DISP
490 # CHECK: daddiu $1, $1, 8 # encoding: [0x08,0x00,0x21,0x64]
491 # CHECK: sw $8, 0($1) # encoding: [0x00,0x00,0x28,0xac]
492
493 lw $10, 655483($4)
494 # CHECK: lui $10, 10 # encoding: [0x0a,0x00,0x0a,0x3c]
495 # CHECK: daddu $10, $10, $4 # encoding: [0x2d,0x50,0x44,0x01]
496 # CHECK: lw $10, 123($10) # encoding: [0x7b,0x00,0x4a,0x8d]
497 sw $10, 123456($9)
498 # CHECK: lui $1, 2 # encoding: [0x02,0x00,0x01,0x3c]
499 # CHECK: daddu $1, $1, $9 # encoding: [0x2d,0x08,0x29,0x00]
500 # CHECK: sw $10, -7616($1) # encoding: [0x40,0xe2,0x2a,0xac]
501
502 lw $8, symbol+8
503 # CHECK: ld $8, %got_disp(symbol)($gp) # encoding: [A,A,0x88,0xdf]
504 # CHECK: # fixup A - offset: 0, value: %got_disp(symbol), kind: fixup_Mips_GOT_DISP
505 # CHECK: daddiu $8, $8, 8 # encoding: [0x08,0x00,0x08,0x65]
506 # CHECK: lw $8, 0($8) # encoding: [0x00,0x00,0x08,0x8d]
507 sw $8, symbol+8
508 # CHECK: ld $1, %got_disp(symbol)($gp) # encoding: [A,A,0x81,0xdf]
509 # CHECK: # fixup A - offset: 0, value: %got_disp(symbol), kind: fixup_Mips_GOT_DISP
510 # CHECK: daddiu $1, $1, 8 # encoding: [0x08,0x00,0x21,0x64]
511 # CHECK: sw $8, 0($1) # encoding: [0x00,0x00,0x28,0xac]
512
513 ldc1 $f0, symbol
514 # CHECK: ld $1, %got_disp(symbol)($gp) # encoding: [A,A,0x81,0xdf]
515 # CHECK: # fixup A - offset: 0, value: %got_disp(symbol), kind: fixup_Mips_GOT_DISP
516 # CHECK: ldc1 $f0, 0($1) # encoding: [0x00,0x00,0x20,0xd4]
517 sdc1 $f0, symbol
518 # CHECK: ld $1, %got_disp(symbol)($gp) # encoding: [A,A,0x81,0xdf]
519 # CHECK: # fixup A - offset: 0, value: %got_disp(symbol), kind: fixup_Mips_GOT_DISP
520 # CHECK: sdc1 $f0, 0($1) # encoding: [0x00,0x00,0x20,0xf4]