1 | //===-- AVRMCInstLower.cpp - Convert AVR MachineInstr to an MCInst --------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file contains code to lower AVR MachineInstrs to their corresponding |
10 | // MCInst records. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #include "AVRMCInstLower.h" |
15 | #include "AVRInstrInfo.h" |
16 | #include "MCTargetDesc/AVRMCExpr.h" |
17 | |
18 | #include "llvm/CodeGen/AsmPrinter.h" |
19 | #include "llvm/IR/Mangler.h" |
20 | #include "llvm/MC/MCInst.h" |
21 | #include "llvm/Support/ErrorHandling.h" |
22 | |
23 | namespace llvm { |
24 | |
25 | MCOperand |
26 | AVRMCInstLower::lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym, |
27 | const AVRSubtarget &Subtarget) const { |
28 | unsigned char TF = MO.getTargetFlags(); |
29 | const MCExpr *Expr = MCSymbolRefExpr::create(Symbol: Sym, Ctx); |
30 | |
31 | bool IsNegated = false; |
32 | if (TF & AVRII::MO_NEG) { |
33 | IsNegated = true; |
34 | } |
35 | |
36 | if (!MO.isJTI() && MO.getOffset()) { |
37 | Expr = MCBinaryExpr::createAdd( |
38 | LHS: Expr, RHS: MCConstantExpr::create(Value: MO.getOffset(), Ctx), Ctx); |
39 | } |
40 | |
41 | bool IsFunction = MO.isGlobal() && isa<Function>(Val: MO.getGlobal()); |
42 | |
43 | if (TF & AVRII::MO_LO) { |
44 | if (IsFunction) { |
45 | Expr = |
46 | AVRMCExpr::create(Kind: Subtarget.hasEIJMPCALL() ? AVRMCExpr::VK_AVR_LO8_GS |
47 | : AVRMCExpr::VK_AVR_PM_LO8, |
48 | Expr, isNegated: IsNegated, Ctx); |
49 | } else { |
50 | Expr = AVRMCExpr::create(Kind: AVRMCExpr::VK_AVR_LO8, Expr, isNegated: IsNegated, Ctx); |
51 | } |
52 | } else if (TF & AVRII::MO_HI) { |
53 | if (IsFunction) { |
54 | Expr = |
55 | AVRMCExpr::create(Kind: Subtarget.hasEIJMPCALL() ? AVRMCExpr::VK_AVR_HI8_GS |
56 | : AVRMCExpr::VK_AVR_PM_HI8, |
57 | Expr, isNegated: IsNegated, Ctx); |
58 | } else { |
59 | Expr = AVRMCExpr::create(Kind: AVRMCExpr::VK_AVR_HI8, Expr, isNegated: IsNegated, Ctx); |
60 | } |
61 | } else if (TF != 0) { |
62 | llvm_unreachable("Unknown target flag on symbol operand" ); |
63 | } |
64 | |
65 | return MCOperand::createExpr(Val: Expr); |
66 | } |
67 | |
68 | void AVRMCInstLower::lowerInstruction(const MachineInstr &MI, |
69 | MCInst &OutMI) const { |
70 | auto &Subtarget = MI.getParent()->getParent()->getSubtarget<AVRSubtarget>(); |
71 | OutMI.setOpcode(MI.getOpcode()); |
72 | |
73 | for (MachineOperand const &MO : MI.operands()) { |
74 | MCOperand MCOp; |
75 | |
76 | switch (MO.getType()) { |
77 | default: |
78 | MI.print(OS&: errs()); |
79 | llvm_unreachable("unknown operand type" ); |
80 | case MachineOperand::MO_Register: |
81 | // Ignore all implicit register operands. |
82 | if (MO.isImplicit()) |
83 | continue; |
84 | MCOp = MCOperand::createReg(Reg: MO.getReg()); |
85 | break; |
86 | case MachineOperand::MO_Immediate: |
87 | MCOp = MCOperand::createImm(Val: MO.getImm()); |
88 | break; |
89 | case MachineOperand::MO_GlobalAddress: |
90 | MCOp = |
91 | lowerSymbolOperand(MO, Sym: Printer.getSymbol(GV: MO.getGlobal()), Subtarget); |
92 | break; |
93 | case MachineOperand::MO_ExternalSymbol: |
94 | MCOp = lowerSymbolOperand( |
95 | MO, Sym: Printer.GetExternalSymbolSymbol(Sym: MO.getSymbolName()), Subtarget); |
96 | break; |
97 | case MachineOperand::MO_MachineBasicBlock: |
98 | MCOp = MCOperand::createExpr( |
99 | Val: MCSymbolRefExpr::create(Symbol: MO.getMBB()->getSymbol(), Ctx)); |
100 | break; |
101 | case MachineOperand::MO_RegisterMask: |
102 | continue; |
103 | case MachineOperand::MO_BlockAddress: |
104 | MCOp = lowerSymbolOperand( |
105 | MO, Sym: Printer.GetBlockAddressSymbol(BA: MO.getBlockAddress()), Subtarget); |
106 | break; |
107 | case MachineOperand::MO_JumpTableIndex: |
108 | MCOp = lowerSymbolOperand(MO, Sym: Printer.GetJTISymbol(JTID: MO.getIndex()), |
109 | Subtarget); |
110 | break; |
111 | case MachineOperand::MO_ConstantPoolIndex: |
112 | MCOp = lowerSymbolOperand(MO, Sym: Printer.GetCPISymbol(CPID: MO.getIndex()), |
113 | Subtarget); |
114 | break; |
115 | } |
116 | |
117 | OutMI.addOperand(Op: MCOp); |
118 | } |
119 | } |
120 | |
121 | } // end of namespace llvm |
122 | |