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/AVRMCAsmInfo.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 = AVRMCExpr::create(S: Subtarget.hasEIJMPCALL() ? AVR::S_LO8_GS |
46 | : AVR::S_PM_LO8, |
47 | Expr, isNegated: IsNegated, Ctx); |
48 | } else { |
49 | Expr = AVRMCExpr::create(S: AVR::S_LO8, Expr, isNegated: IsNegated, Ctx); |
50 | } |
51 | } else if (TF & AVRII::MO_HI) { |
52 | if (IsFunction) { |
53 | Expr = AVRMCExpr::create(S: Subtarget.hasEIJMPCALL() ? AVR::S_HI8_GS |
54 | : AVR::S_PM_HI8, |
55 | Expr, isNegated: IsNegated, Ctx); |
56 | } else { |
57 | Expr = AVRMCExpr::create(S: AVR::S_HI8, Expr, isNegated: IsNegated, Ctx); |
58 | } |
59 | } else if (TF != 0) { |
60 | llvm_unreachable("Unknown target flag on symbol operand" ); |
61 | } |
62 | |
63 | return MCOperand::createExpr(Val: Expr); |
64 | } |
65 | |
66 | void AVRMCInstLower::lowerInstruction(const MachineInstr &MI, |
67 | MCInst &OutMI) const { |
68 | auto &Subtarget = MI.getParent()->getParent()->getSubtarget<AVRSubtarget>(); |
69 | OutMI.setOpcode(MI.getOpcode()); |
70 | |
71 | for (MachineOperand const &MO : MI.operands()) { |
72 | MCOperand MCOp; |
73 | |
74 | switch (MO.getType()) { |
75 | default: |
76 | MI.print(OS&: errs()); |
77 | llvm_unreachable("unknown operand type" ); |
78 | case MachineOperand::MO_Register: |
79 | // Ignore all implicit register operands. |
80 | if (MO.isImplicit()) |
81 | continue; |
82 | MCOp = MCOperand::createReg(Reg: MO.getReg()); |
83 | break; |
84 | case MachineOperand::MO_Immediate: |
85 | MCOp = MCOperand::createImm(Val: MO.getImm()); |
86 | break; |
87 | case MachineOperand::MO_GlobalAddress: |
88 | MCOp = |
89 | lowerSymbolOperand(MO, Sym: Printer.getSymbol(GV: MO.getGlobal()), Subtarget); |
90 | break; |
91 | case MachineOperand::MO_ExternalSymbol: |
92 | MCOp = lowerSymbolOperand( |
93 | MO, Sym: Printer.GetExternalSymbolSymbol(Sym: MO.getSymbolName()), Subtarget); |
94 | break; |
95 | case MachineOperand::MO_MachineBasicBlock: |
96 | MCOp = MCOperand::createExpr( |
97 | Val: MCSymbolRefExpr::create(Symbol: MO.getMBB()->getSymbol(), Ctx)); |
98 | break; |
99 | case MachineOperand::MO_RegisterMask: |
100 | continue; |
101 | case MachineOperand::MO_BlockAddress: |
102 | MCOp = lowerSymbolOperand( |
103 | MO, Sym: Printer.GetBlockAddressSymbol(BA: MO.getBlockAddress()), Subtarget); |
104 | break; |
105 | case MachineOperand::MO_JumpTableIndex: |
106 | MCOp = lowerSymbolOperand(MO, Sym: Printer.GetJTISymbol(JTID: MO.getIndex()), |
107 | Subtarget); |
108 | break; |
109 | case MachineOperand::MO_ConstantPoolIndex: |
110 | MCOp = lowerSymbolOperand(MO, Sym: Printer.GetCPISymbol(CPID: MO.getIndex()), |
111 | Subtarget); |
112 | break; |
113 | } |
114 | |
115 | OutMI.addOperand(Op: MCOp); |
116 | } |
117 | } |
118 | |
119 | } // end of namespace llvm |
120 | |