]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/patches/patch-27-llvm-r222587-arm-add-pc.diff
Upgrade our copy of clang and llvm to 3.5.1 release. This is a bugfix
[FreeBSD/FreeBSD.git] / contrib / llvm / patches / patch-27-llvm-r222587-arm-add-pc.diff
1 Pull in r222587 from upstream llvm trunk (by Jörg Sonnenberger):
2
3   Fix transformation of add with pc argument to adr for non-immediate
4   arguments.
5
6 This fixes an "Unimplemented" error when assembling certain ARM add
7 instructions with pc-relative arguments.
8
9 Reported by:    sbruno
10 PR:             196412, 196423
11
12 Introduced here: http://svnweb.freebsd.org/changeset/base/276537
13
14 Index: lib/Target/ARM/AsmParser/ARMAsmParser.cpp
15 ===================================================================
16 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp
17 +++ lib/Target/ARM/AsmParser/ARMAsmParser.cpp
18 @@ -314,7 +314,7 @@ class ARMAsmParser : public MCTargetAsmParser {
19    void cvtThumbBranches(MCInst &Inst, const OperandVector &);
20  
21    bool validateInstruction(MCInst &Inst, const OperandVector &Ops);
22 -  bool processInstruction(MCInst &Inst, const OperandVector &Ops);
23 +  bool processInstruction(MCInst &Inst, const OperandVector &Ops, MCStreamer &Out);
24    bool shouldOmitCCOutOperand(StringRef Mnemonic, OperandVector &Operands);
25    bool shouldOmitPredicateOperand(StringRef Mnemonic, OperandVector &Operands);
26  
27 @@ -6175,7 +6175,8 @@ static unsigned getRealVLDOpcode(unsigned Opc, uns
28  }
29  
30  bool ARMAsmParser::processInstruction(MCInst &Inst,
31 -                                      const OperandVector &Operands) {
32 +                                      const OperandVector &Operands,
33 +                                      MCStreamer &Out) {
34    switch (Inst.getOpcode()) {
35    // Alias for alternate form of 'ldr{,b}t Rt, [Rn], #imm' instruction.
36    case ARM::LDRT_POST:
37 @@ -6216,12 +6217,31 @@ bool ARMAsmParser::processInstruction(MCInst &Inst
38    // Alias for alternate form of 'ADR Rd, #imm' instruction.
39    case ARM::ADDri: {
40      if (Inst.getOperand(1).getReg() != ARM::PC ||
41 -        Inst.getOperand(5).getReg() != 0)
42 +        Inst.getOperand(5).getReg() != 0 ||
43 +        !(Inst.getOperand(2).isExpr() || Inst.getOperand(2).isImm()))
44        return false;
45      MCInst TmpInst;
46      TmpInst.setOpcode(ARM::ADR);
47      TmpInst.addOperand(Inst.getOperand(0));
48 -    TmpInst.addOperand(Inst.getOperand(2));
49 +    if (Inst.getOperand(2).isImm()) {
50 +      TmpInst.addOperand(Inst.getOperand(2));
51 +    } else {
52 +      // Turn PC-relative expression into absolute expression.
53 +      // Reading PC provides the start of the current instruction + 8 and
54 +      // the transform to adr is biased by that.
55 +      MCSymbol *Dot = getContext().CreateTempSymbol();
56 +      Out.EmitLabel(Dot);
57 +      const MCExpr *OpExpr = Inst.getOperand(2).getExpr();
58 +      const MCExpr *InstPC = MCSymbolRefExpr::Create(Dot,
59 +                                                     MCSymbolRefExpr::VK_None,
60 +                                                     getContext());
61 +      const MCExpr *Const8 = MCConstantExpr::Create(8, getContext());
62 +      const MCExpr *ReadPC = MCBinaryExpr::CreateAdd(InstPC, Const8,
63 +                                                     getContext());
64 +      const MCExpr *FixupAddr = MCBinaryExpr::CreateAdd(ReadPC, OpExpr,
65 +                                                        getContext());
66 +      TmpInst.addOperand(MCOperand::CreateExpr(FixupAddr));
67 +    }
68      TmpInst.addOperand(Inst.getOperand(3));
69      TmpInst.addOperand(Inst.getOperand(4));
70      Inst = TmpInst;
71 @@ -8061,7 +8081,7 @@ bool ARMAsmParser::MatchAndEmitInstruction(SMLoc I
72        // encoding is selected. Loop on it while changes happen so the
73        // individual transformations can chain off each other. E.g.,
74        // tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8)
75 -      while (processInstruction(Inst, Operands))
76 +      while (processInstruction(Inst, Operands, Out))
77          ;
78  
79        // Only after the instruction is fully processed, we can validate it
80 Index: test/MC/ARM/basic-arm-instructions.s
81 ===================================================================
82 --- test/MC/ARM/basic-arm-instructions.s
83 +++ test/MC/ARM/basic-arm-instructions.s
84 @@ -191,8 +191,10 @@ Lforward:
85  
86         add r0, #-4
87         add r4, r5, #-21
88 -        add r0, pc, #0xc0000000
89 +       add r0, pc, #0xc0000000
90  
91 +       add r0, pc, #(Lback - .)
92 +
93  @ CHECK: add   r4, r5, #61440          @ encoding: [0x0f,0x4a,0x85,0xe2]
94  @ CHECK: add   r4, r5, r6              @ encoding: [0x06,0x40,0x85,0xe0]
95  @ CHECK: add   r4, r5, r6, lsl #5      @ encoding: [0x86,0x42,0x85,0xe0]
96 @@ -222,7 +224,11 @@ Lforward:
97  
98  @ CHECK: sub   r0, r0, #4              @ encoding: [0x04,0x00,0x40,0xe2]
99  @ CHECK: sub   r4, r5, #21             @ encoding: [0x15,0x40,0x45,0xe2]
100 -@ CHECK: adr    r0, #-1073741824        @ encoding: [0x03,0x01,0x8f,0xe2]
101 +@ CHECK: adr   r0, #-1073741824        @ encoding: [0x03,0x01,0x8f,0xe2]
102 +@ CHECK:        Ltmp0:
103 +@ CHECK-NEXT:   Ltmp1:
104 +@ CHECK-NEXT:   adr    r0, (Ltmp1+8)+(Lback-Ltmp0) @ encoding: [A,A,0x0f'A',0xe2'A']
105 +@ CHECK-NEXT:                           @   fixup A - offset: 0, value: (Ltmp1+8)+(Lback-Ltmp0), kind: fixup_arm_adr_pcrel_12
106  
107      @ Test right shift by 32, which is encoded as 0
108      add r3, r1, r2, lsr #32