LoongArchAsmPrinter.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. //===- LoongArchAsmPrinter.cpp - LoongArch LLVM Assembly Printer -*- C++ -*--=//
  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 a printer that converts from our internal representation
  10. // of machine-dependent LLVM code to GAS-format LoongArch assembly language.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "LoongArchAsmPrinter.h"
  14. #include "LoongArch.h"
  15. #include "LoongArchTargetMachine.h"
  16. #include "MCTargetDesc/LoongArchInstPrinter.h"
  17. #include "TargetInfo/LoongArchTargetInfo.h"
  18. #include "llvm/CodeGen/AsmPrinter.h"
  19. #include "llvm/MC/TargetRegistry.h"
  20. using namespace llvm;
  21. #define DEBUG_TYPE "loongarch-asm-printer"
  22. // Simple pseudo-instructions have their lowering (with expansion to real
  23. // instructions) auto-generated.
  24. #include "LoongArchGenMCPseudoLowering.inc"
  25. void LoongArchAsmPrinter::emitInstruction(const MachineInstr *MI) {
  26. LoongArch_MC::verifyInstructionPredicates(
  27. MI->getOpcode(), getSubtargetInfo().getFeatureBits());
  28. // Do any auto-generated pseudo lowerings.
  29. if (emitPseudoExpansionLowering(*OutStreamer, MI))
  30. return;
  31. MCInst TmpInst;
  32. if (!lowerLoongArchMachineInstrToMCInst(MI, TmpInst, *this))
  33. EmitToStreamer(*OutStreamer, TmpInst);
  34. }
  35. bool LoongArchAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
  36. const char *ExtraCode,
  37. raw_ostream &OS) {
  38. // First try the generic code, which knows about modifiers like 'c' and 'n'.
  39. if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS))
  40. return false;
  41. const MachineOperand &MO = MI->getOperand(OpNo);
  42. if (ExtraCode && ExtraCode[0]) {
  43. if (ExtraCode[1] != 0)
  44. return true; // Unknown modifier.
  45. switch (ExtraCode[0]) {
  46. default:
  47. return true; // Unknown modifier.
  48. case 'z': // Print $zero register if zero, regular printing otherwise.
  49. if (MO.isImm() && MO.getImm() == 0) {
  50. OS << '$' << LoongArchInstPrinter::getRegisterName(LoongArch::R0);
  51. return false;
  52. }
  53. break;
  54. // TODO: handle other extra codes if any.
  55. }
  56. }
  57. switch (MO.getType()) {
  58. case MachineOperand::MO_Immediate:
  59. OS << MO.getImm();
  60. return false;
  61. case MachineOperand::MO_Register:
  62. OS << '$' << LoongArchInstPrinter::getRegisterName(MO.getReg());
  63. return false;
  64. case MachineOperand::MO_GlobalAddress:
  65. PrintSymbolOperand(MO, OS);
  66. return false;
  67. default:
  68. llvm_unreachable("not implemented");
  69. }
  70. return true;
  71. }
  72. bool LoongArchAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
  73. unsigned OpNo,
  74. const char *ExtraCode,
  75. raw_ostream &OS) {
  76. // TODO: handle extra code.
  77. if (ExtraCode)
  78. return true;
  79. // We only support memory operands like "Base + Offset", where base must be a
  80. // register, and offset can be a register or an immediate value.
  81. const MachineOperand &BaseMO = MI->getOperand(OpNo);
  82. // Base address must be a register.
  83. if (!BaseMO.isReg())
  84. return true;
  85. // Print the base address register.
  86. OS << "$" << LoongArchInstPrinter::getRegisterName(BaseMO.getReg());
  87. // Print the offset operand.
  88. const MachineOperand &OffsetMO = MI->getOperand(OpNo + 1);
  89. if (OffsetMO.isReg())
  90. OS << ", $" << LoongArchInstPrinter::getRegisterName(OffsetMO.getReg());
  91. else if (OffsetMO.isImm())
  92. OS << ", " << OffsetMO.getImm();
  93. else
  94. return true;
  95. return false;
  96. }
  97. bool LoongArchAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
  98. AsmPrinter::runOnMachineFunction(MF);
  99. return true;
  100. }
  101. // Force static initialization.
  102. extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchAsmPrinter() {
  103. RegisterAsmPrinter<LoongArchAsmPrinter> X(getTheLoongArch32Target());
  104. RegisterAsmPrinter<LoongArchAsmPrinter> Y(getTheLoongArch64Target());
  105. }