mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-20 11:29:24 +00:00
- Modifications from the last patch included (issues pointed by Evan Cheng are now fixed). - Added more MipsI instructions. - Added more patterns to match branch instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37461 91177308-0d34-0410-b5e6-96231b3b80d8
115 lines
3.8 KiB
C++
115 lines
3.8 KiB
C++
//===- MipsInstrInfo.cpp - Mips Instruction Information ---------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file was developed by Bruno Cardoso Lopes and is distributed under the
|
|
// University of Illinois Open Source License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file contains the Mips implementation of the TargetInstrInfo class.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "Mips.h"
|
|
#include "MipsInstrInfo.h"
|
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
|
#include "MipsGenInstrInfo.inc"
|
|
|
|
using namespace llvm;
|
|
|
|
// TODO: Add the subtarget support on this constructor
|
|
MipsInstrInfo::MipsInstrInfo(MipsTargetMachine &tm)
|
|
: TargetInstrInfo(MipsInsts, sizeof(MipsInsts)/sizeof(MipsInsts[0])),
|
|
TM(tm), RI(*this) {}
|
|
|
|
static bool isZeroImm(const MachineOperand &op) {
|
|
return op.isImmediate() && op.getImmedValue() == 0;
|
|
}
|
|
|
|
/// Return true if the instruction is a register to register move and
|
|
/// leave the source and dest operands in the passed parameters.
|
|
bool MipsInstrInfo::
|
|
isMoveInstr(const MachineInstr &MI, unsigned &SrcReg, unsigned &DstReg) const
|
|
{
|
|
// addu $dst, $src, $zero || addu $dst, $zero, $src
|
|
// or $dst, $src, $zero || or $dst, $zero, $src
|
|
if ((MI.getOpcode() == Mips::ADDu) || (MI.getOpcode() == Mips::OR))
|
|
{
|
|
if (MI.getOperand(1).getReg() == Mips::ZERO) {
|
|
DstReg = MI.getOperand(0).getReg();
|
|
SrcReg = MI.getOperand(2).getReg();
|
|
return true;
|
|
} else if (MI.getOperand(2).getReg() == Mips::ZERO) {
|
|
DstReg = MI.getOperand(0).getReg();
|
|
SrcReg = MI.getOperand(1).getReg();
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// addiu $dst, $src, 0
|
|
if (MI.getOpcode() == Mips::ADDiu)
|
|
{
|
|
if ((MI.getOperand(1).isRegister()) && (isZeroImm(MI.getOperand(2)))) {
|
|
DstReg = MI.getOperand(0).getReg();
|
|
SrcReg = MI.getOperand(1).getReg();
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// isLoadFromStackSlot - If the specified machine instruction is a direct
|
|
/// load from a stack slot, return the virtual or physical register number of
|
|
/// the destination along with the FrameIndex of the loaded stack slot. If
|
|
/// not, return 0. This predicate must return 0 if the instruction has
|
|
/// any side effects other than loading from the stack slot.
|
|
unsigned MipsInstrInfo::
|
|
isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const
|
|
{
|
|
// TODO: add lhu, lbu ???
|
|
if (MI->getOpcode() == Mips::LW)
|
|
{
|
|
if ((MI->getOperand(2).isFrameIndex()) && // is a stack slot
|
|
(MI->getOperand(1).isImmediate()) && // the imm is zero
|
|
(isZeroImm(MI->getOperand(1))))
|
|
{
|
|
FrameIndex = MI->getOperand(2).getFrameIndex();
|
|
return MI->getOperand(0).getReg();
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/// isStoreToStackSlot - If the specified machine instruction is a direct
|
|
/// store to a stack slot, return the virtual or physical register number of
|
|
/// the source reg along with the FrameIndex of the loaded stack slot. If
|
|
/// not, return 0. This predicate must return 0 if the instruction has
|
|
/// any side effects other than storing to the stack slot.
|
|
unsigned MipsInstrInfo::
|
|
isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const
|
|
{
|
|
// TODO: add sb, sh ???
|
|
if (MI->getOpcode() == Mips::SW) {
|
|
if ((MI->getOperand(0).isFrameIndex()) && // is a stack slot
|
|
(MI->getOperand(1).isImmediate()) && // the imm is zero
|
|
(isZeroImm(MI->getOperand(1))))
|
|
{
|
|
FrameIndex = MI->getOperand(0).getFrameIndex();
|
|
return MI->getOperand(2).getReg();
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
unsigned MipsInstrInfo::
|
|
InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
|
|
MachineBasicBlock *FBB, const std::vector<MachineOperand> &Cond)
|
|
const
|
|
{
|
|
// TODO: add Mips::J here.
|
|
assert(0 && "Cant handle any kind of branches!");
|
|
return 1;
|
|
}
|