1//===-- RISCVInlineAsmLowering.cpp ----------------------------------------===//
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/// \file
10/// This file implements the lowering from LLVM IR inline asm to MIR INLINEASM
11///
12//===----------------------------------------------------------------------===//
13
14#include "RISCVInlineAsmLowering.h"
15#include "llvm/ADT/StringRef.h"
16#include "llvm/CodeGen/GlobalISel/InlineAsmLowering.h"
17#include "llvm/CodeGen/MachineOperand.h"
18#include "llvm/IR/Constants.h"
19#include "llvm/Support/MathExtras.h"
20
21using namespace llvm;
22
23RISCVInlineAsmLowering::RISCVInlineAsmLowering(const TargetLowering *TLI)
24 : InlineAsmLowering(TLI) {}
25
26bool RISCVInlineAsmLowering::lowerAsmOperandForConstraint(
27 Value *Val, StringRef Constraint, std::vector<MachineOperand> &Ops,
28 MachineIRBuilder &MIRBuilder) const {
29 if (Constraint.size() != 1)
30 return false;
31
32 // RISC-V specific constraints.
33 switch (Constraint[0]) {
34 case 'I': // 12-bit signed immediate operand.
35 if (ConstantInt *CI = dyn_cast<ConstantInt>(Val)) {
36 int64_t ExtVal = CI->getSExtValue();
37 if (isInt<12>(x: ExtVal)) {
38 Ops.push_back(x: MachineOperand::CreateImm(Val: ExtVal));
39 return true;
40 }
41 }
42 return false;
43 case 'J': // Integer zero operand.
44 if (ConstantInt *CI = dyn_cast<ConstantInt>(Val)) {
45 if (CI->isZero()) {
46 Ops.push_back(x: MachineOperand::CreateImm(Val: 0));
47 return true;
48 }
49 }
50 return false;
51 case 'K': // 5-bit unsigned immediate operand.
52 if (ConstantInt *CI = dyn_cast<ConstantInt>(Val)) {
53 uint64_t ExtVal = CI->getZExtValue();
54 if (isUInt<5>(x: ExtVal)) {
55 Ops.push_back(x: MachineOperand::CreateImm(Val: ExtVal));
56 return true;
57 }
58 }
59 return false;
60 case 'S': // Alias for s.
61 return InlineAsmLowering::lowerAsmOperandForConstraint(Val, Constraint: "s", Ops,
62 MIRBuilder);
63 default:
64 // Target-independent constraints.
65 return InlineAsmLowering::lowerAsmOperandForConstraint(Val, Constraint, Ops,
66 MIRBuilder);
67 }
68}
69