mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-09 11:25:55 +00:00
MC machine encoding for simple aritmetic instructions that use a shifted
register operand. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116259 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -50,6 +50,16 @@ namespace ARM_AM {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline unsigned getShiftOpcEncoding(ShiftOpc Op) {
|
||||||
|
switch (Op) {
|
||||||
|
default: assert(0 && "Unknown shift opc!");
|
||||||
|
case ARM_AM::asr: return 2;
|
||||||
|
case ARM_AM::lsl: return 0;
|
||||||
|
case ARM_AM::lsr: return 1;
|
||||||
|
case ARM_AM::ror: return 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline ShiftOpc getShiftOpcForNode(SDValue N) {
|
static inline ShiftOpc getShiftOpcForNode(SDValue N) {
|
||||||
switch (N.getOpcode()) {
|
switch (N.getOpcode()) {
|
||||||
default: return ARM_AM::no_shift;
|
default: return ARM_AM::no_shift;
|
||||||
|
@@ -160,6 +160,11 @@ namespace ARMII {
|
|||||||
//===------------------------------------------------------------------===//
|
//===------------------------------------------------------------------===//
|
||||||
// Field shifts - such shifts are used to set field while generating
|
// Field shifts - such shifts are used to set field while generating
|
||||||
// machine instructions.
|
// machine instructions.
|
||||||
|
//
|
||||||
|
// FIXME: This list will need adjusting/fixing as the MC code emitter
|
||||||
|
// takes shape and the ARMCodeEmitter.cpp bits go away.
|
||||||
|
ShiftTypeShift = 4,
|
||||||
|
|
||||||
M_BitShift = 5,
|
M_BitShift = 5,
|
||||||
ShiftImmShift = 5,
|
ShiftImmShift = 5,
|
||||||
ShiftShift = 7,
|
ShiftShift = 7,
|
||||||
|
@@ -494,7 +494,13 @@ multiclass AsI1_bin_irs<bits<4> opcod, string opc,
|
|||||||
def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
|
def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
|
||||||
iis, opc, "\t$dst, $a, $b",
|
iis, opc, "\t$dst, $a, $b",
|
||||||
[(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
|
[(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
|
||||||
|
bits<4> Rd;
|
||||||
|
bits<4> Rn;
|
||||||
|
bits<4> Rm;
|
||||||
let Inst{25} = 0;
|
let Inst{25} = 0;
|
||||||
|
let Inst{3-0} = Rm;
|
||||||
|
let Inst{15-12} = Rd;
|
||||||
|
let Inst{19-16} = Rn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#define DEBUG_TYPE "arm-emitter"
|
#define DEBUG_TYPE "arm-emitter"
|
||||||
#include "ARM.h"
|
#include "ARM.h"
|
||||||
|
#include "ARMAddressingModes.h"
|
||||||
#include "ARMInstrInfo.h"
|
#include "ARMInstrInfo.h"
|
||||||
#include "llvm/MC/MCCodeEmitter.h"
|
#include "llvm/MC/MCCodeEmitter.h"
|
||||||
#include "llvm/MC/MCExpr.h"
|
#include "llvm/MC/MCExpr.h"
|
||||||
@@ -139,8 +140,27 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
++MCNumEmitted; // Keep track of the # of mi's emitted
|
++MCNumEmitted; // Keep track of the # of mi's emitted
|
||||||
|
// FIXME: TableGen doesn't deal well with operands that expand to multiple
|
||||||
|
// machine instruction operands, so for now we'll fix those up here.
|
||||||
switch (Opcode) {
|
switch (Opcode) {
|
||||||
//FIXME: Any non-pseudos that need special handling, if there are any...
|
case ARM::ADDrs:
|
||||||
|
case ARM::ANDrs:
|
||||||
|
case ARM::BICrs:
|
||||||
|
case ARM::EORrs:
|
||||||
|
case ARM::ORRrs:
|
||||||
|
case ARM::SUBrs: {
|
||||||
|
// The so_reg operand needs the shift ammount encoded.
|
||||||
|
unsigned Value = getBinaryCodeForInstr(MI);
|
||||||
|
unsigned ShVal = MI.getOperand(4).getImm();
|
||||||
|
unsigned ShType = ARM_AM::getShiftOpcEncoding(ARM_AM::getSORegShOp(ShVal));
|
||||||
|
unsigned ShAmt = ARM_AM::getSORegOffset(ShVal);
|
||||||
|
|
||||||
|
Value |= ShType << ARMII::ShiftTypeShift;
|
||||||
|
Value |= ShAmt << ARMII::ShiftShift;
|
||||||
|
|
||||||
|
EmitConstant(Value, 4, CurByte, OS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
unsigned Value = getBinaryCodeForInstr(MI);
|
unsigned Value = getBinaryCodeForInstr(MI);
|
||||||
EmitConstant(Value, 4, CurByte, OS);
|
EmitConstant(Value, 4, CurByte, OS);
|
||||||
|
@@ -8,8 +8,8 @@
|
|||||||
define i32 @foo(i32 %a, i32 %b) nounwind ssp {
|
define i32 @foo(i32 %a, i32 %b) nounwind ssp {
|
||||||
entry:
|
entry:
|
||||||
; CHECK: foo
|
; CHECK: foo
|
||||||
; CHECK: 0xf0,0x00,0xf0,0x07
|
; CHECK: trap @ encoding: [0xf0,0x00,0xf0,0x07]
|
||||||
; CHECK: 0x1e,0xff,0x2f,0xe1
|
; CHECK: bx lr @ encoding: [0x1e,0xff,0x2f,0xe1]
|
||||||
|
|
||||||
tail call void @llvm.trap()
|
tail call void @llvm.trap()
|
||||||
ret i32 undef
|
ret i32 undef
|
||||||
@@ -18,9 +18,21 @@ entry:
|
|||||||
define i32 @f2(i32 %a, i32 %b) nounwind readnone ssp {
|
define i32 @f2(i32 %a, i32 %b) nounwind readnone ssp {
|
||||||
entry:
|
entry:
|
||||||
; CHECK: f2
|
; CHECK: f2
|
||||||
; CHECK: 0x00,0x00,0x81,0xe0
|
; CHECK: add r0, r1, r0 @ encoding: [0x00,0x00,0x81,0xe0]
|
||||||
; CHECK: 0x1e,0xff,0x2f,0xe1
|
; CHECK: bx lr @ encoding: [0x1e,0xff,0x2f,0xe1]
|
||||||
%add = add nsw i32 %b, %a
|
%add = add nsw i32 %b, %a
|
||||||
ret i32 %add
|
ret i32 %add
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
define i32 @f3(i32 %a, i32 %b) nounwind readnone ssp {
|
||||||
|
entry:
|
||||||
|
; CHECK: f3
|
||||||
|
; CHECK: add r0, r0, r1, lsl #3 @ encoding: [0x81,0x01,0x80,0xe0]
|
||||||
|
; CHECK: bx lr @ encoding: [0x1e,0xff,0x2f,0xe1]
|
||||||
|
%mul = shl i32 %b, 3
|
||||||
|
%add = add nsw i32 %mul, %a
|
||||||
|
ret i32 %add
|
||||||
|
}
|
||||||
|
|
||||||
declare void @llvm.trap() nounwind
|
declare void @llvm.trap() nounwind
|
||||||
|
Reference in New Issue
Block a user