mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-26 05:32:25 +00:00
587daedce2
booleans. This gives a better indication of what the "addReg()" is doing. Remembering what all of those booleans mean isn't easy, especially if you aren't spending all of your time in that code. I took Jakob's suggestion and made it illegal to pass in "true" for the flag. This should hopefully prevent any unintended misuse of this (by reverting to the old way of using addReg()). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@71722 91177308-0d34-0410-b5e6-96231b3b80d8
169 lines
6.4 KiB
C++
169 lines
6.4 KiB
C++
//===-- X86InstrBuilder.h - Functions to aid building x86 insts -*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file exposes functions that may be used with BuildMI from the
|
|
// MachineInstrBuilder.h file to handle X86'isms in a clean way.
|
|
//
|
|
// The BuildMem function may be used with the BuildMI function to add entire
|
|
// memory references in a single, typed, function call. X86 memory references
|
|
// can be very complex expressions (described in the README), so wrapping them
|
|
// up behind an easier to use interface makes sense. Descriptions of the
|
|
// functions are included below.
|
|
//
|
|
// For reference, the order of operands for memory references is:
|
|
// (Operand), Base, Scale, Index, Displacement.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef X86INSTRBUILDER_H
|
|
#define X86INSTRBUILDER_H
|
|
|
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
|
#include "llvm/CodeGen/PseudoSourceValue.h"
|
|
|
|
namespace llvm {
|
|
|
|
/// X86AddressMode - This struct holds a generalized full x86 address mode.
|
|
/// The base register can be a frame index, which will eventually be replaced
|
|
/// with BP or SP and Disp being offsetted accordingly. The displacement may
|
|
/// also include the offset of a global value.
|
|
struct X86AddressMode {
|
|
enum {
|
|
RegBase,
|
|
FrameIndexBase
|
|
} BaseType;
|
|
|
|
union {
|
|
unsigned Reg;
|
|
int FrameIndex;
|
|
} Base;
|
|
|
|
unsigned Scale;
|
|
unsigned IndexReg;
|
|
unsigned Disp;
|
|
GlobalValue *GV;
|
|
|
|
X86AddressMode() : BaseType(RegBase), Scale(1), IndexReg(0), Disp(0), GV(0) {
|
|
Base.Reg = 0;
|
|
}
|
|
};
|
|
|
|
/// addDirectMem - This function is used to add a direct memory reference to the
|
|
/// current instruction -- that is, a dereference of an address in a register,
|
|
/// with no scale, index or displacement. An example is: DWORD PTR [EAX].
|
|
///
|
|
inline const MachineInstrBuilder &addDirectMem(const MachineInstrBuilder &MIB,
|
|
unsigned Reg) {
|
|
// Because memory references are always represented with four
|
|
// values, this adds: Reg, [1, NoReg, 0] to the instruction.
|
|
return MIB.addReg(Reg).addImm(1).addReg(0).addImm(0);
|
|
}
|
|
|
|
inline const MachineInstrBuilder &addLeaOffset(const MachineInstrBuilder &MIB,
|
|
int Offset) {
|
|
return MIB.addImm(1).addReg(0).addImm(Offset);
|
|
}
|
|
|
|
inline const MachineInstrBuilder &addOffset(const MachineInstrBuilder &MIB,
|
|
int Offset) {
|
|
return addLeaOffset(MIB, Offset).addReg(0);
|
|
}
|
|
|
|
/// addRegOffset - This function is used to add a memory reference of the form
|
|
/// [Reg + Offset], i.e., one with no scale or index, but with a
|
|
/// displacement. An example is: DWORD PTR [EAX + 4].
|
|
///
|
|
inline const MachineInstrBuilder &addRegOffset(const MachineInstrBuilder &MIB,
|
|
unsigned Reg, bool isKill,
|
|
int Offset) {
|
|
return addOffset(MIB.addReg(Reg, getKillRegState(isKill)), Offset);
|
|
}
|
|
|
|
inline const MachineInstrBuilder &addLeaRegOffset(const MachineInstrBuilder &MIB,
|
|
unsigned Reg, bool isKill,
|
|
int Offset) {
|
|
return addLeaOffset(MIB.addReg(Reg, getKillRegState(isKill)), Offset);
|
|
}
|
|
|
|
/// addRegReg - This function is used to add a memory reference of the form:
|
|
/// [Reg + Reg].
|
|
inline const MachineInstrBuilder &addRegReg(const MachineInstrBuilder &MIB,
|
|
unsigned Reg1, bool isKill1,
|
|
unsigned Reg2, bool isKill2) {
|
|
return MIB.addReg(Reg1, getKillRegState(isKill1)).addImm(1)
|
|
.addReg(Reg2, getKillRegState(isKill2)).addImm(0);
|
|
}
|
|
|
|
inline const MachineInstrBuilder &addLeaAddress(const MachineInstrBuilder &MIB,
|
|
const X86AddressMode &AM) {
|
|
assert (AM.Scale == 1 || AM.Scale == 2 || AM.Scale == 4 || AM.Scale == 8);
|
|
|
|
if (AM.BaseType == X86AddressMode::RegBase)
|
|
MIB.addReg(AM.Base.Reg);
|
|
else if (AM.BaseType == X86AddressMode::FrameIndexBase)
|
|
MIB.addFrameIndex(AM.Base.FrameIndex);
|
|
else
|
|
assert (0);
|
|
MIB.addImm(AM.Scale).addReg(AM.IndexReg);
|
|
if (AM.GV)
|
|
return MIB.addGlobalAddress(AM.GV, AM.Disp);
|
|
else
|
|
return MIB.addImm(AM.Disp);
|
|
}
|
|
|
|
inline const MachineInstrBuilder &addFullAddress(const MachineInstrBuilder &MIB,
|
|
const X86AddressMode &AM) {
|
|
return addLeaAddress(MIB, AM).addReg(0);
|
|
}
|
|
|
|
/// addFrameReference - This function is used to add a reference to the base of
|
|
/// an abstract object on the stack frame of the current function. This
|
|
/// reference has base register as the FrameIndex offset until it is resolved.
|
|
/// This allows a constant offset to be specified as well...
|
|
///
|
|
inline const MachineInstrBuilder &
|
|
addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset = 0) {
|
|
MachineInstr *MI = MIB;
|
|
MachineFunction &MF = *MI->getParent()->getParent();
|
|
MachineFrameInfo &MFI = *MF.getFrameInfo();
|
|
const TargetInstrDesc &TID = MI->getDesc();
|
|
unsigned Flags = 0;
|
|
if (TID.mayLoad())
|
|
Flags |= MachineMemOperand::MOLoad;
|
|
if (TID.mayStore())
|
|
Flags |= MachineMemOperand::MOStore;
|
|
MachineMemOperand MMO(PseudoSourceValue::getFixedStack(FI),
|
|
Flags,
|
|
MFI.getObjectOffset(FI) + Offset,
|
|
MFI.getObjectSize(FI),
|
|
MFI.getObjectAlignment(FI));
|
|
return addOffset(MIB.addFrameIndex(FI), Offset)
|
|
.addMemOperand(MMO);
|
|
}
|
|
|
|
/// addConstantPoolReference - This function is used to add a reference to the
|
|
/// base of a constant value spilled to the per-function constant pool. The
|
|
/// reference uses the abstract ConstantPoolIndex which is retained until
|
|
/// either machine code emission or assembly output. In PIC mode on x86-32,
|
|
/// the GlobalBaseReg parameter can be used to make this a
|
|
/// GlobalBaseReg-relative reference.
|
|
///
|
|
inline const MachineInstrBuilder &
|
|
addConstantPoolReference(const MachineInstrBuilder &MIB, unsigned CPI,
|
|
unsigned GlobalBaseReg = 0) {
|
|
//FIXME: factor this
|
|
return MIB.addReg(GlobalBaseReg).addImm(1).addReg(0)
|
|
.addConstantPoolIndex(CPI).addReg(0);
|
|
}
|
|
|
|
} // End llvm namespace
|
|
|
|
#endif
|