mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
Implement multiply operator
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4506 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
bbe75fe78f
commit
ca9671d864
@ -61,6 +61,7 @@ namespace {
|
||||
// Arithmetic operators
|
||||
void visitAdd(BinaryOperator &B) { visitSimpleBinary(B, 0); }
|
||||
void visitSub(BinaryOperator &B) { visitSimpleBinary(B, 1); }
|
||||
void visitMul(BinaryOperator &B);
|
||||
|
||||
// Bitwise operators
|
||||
void visitAnd(BinaryOperator &B) { visitSimpleBinary(B, 2); }
|
||||
@ -221,7 +222,33 @@ void ISel::visitSimpleBinary(BinaryOperator &B, unsigned OperatorClass) {
|
||||
BuildMI(BB, Opcode, 2, getReg(B)).addReg(Op0r).addReg(Op1r);
|
||||
}
|
||||
|
||||
/// visitMul - Multiplies are not simple binary operators because they must deal
|
||||
/// with the EAX register explicitly.
|
||||
///
|
||||
void ISel::visitMul(BinaryOperator &I) {
|
||||
unsigned Class = getClass(I.getType());
|
||||
if (Class > 2) // FIXME: Handle longs
|
||||
visitInstruction(I);
|
||||
|
||||
static const unsigned Regs[] ={ X86::AL , X86::AX , X86::EAX };
|
||||
static const unsigned MulOpcode[]={ X86::MULrr8, X86::MULrr16, X86::MULrr32 };
|
||||
static const unsigned MovOpcode[]={ X86::MOVrr8, X86::MOVrr16, X86::MOVrr32 };
|
||||
|
||||
unsigned Reg = Regs[Class];
|
||||
unsigned Op0Reg = getReg(I.getOperand(1));
|
||||
unsigned Op1Reg = getReg(I.getOperand(1));
|
||||
|
||||
// Put the first operand into one of the A registers...
|
||||
BuildMI(BB, MovOpcode[Class], 1, Reg).addReg(Op0Reg);
|
||||
|
||||
// Emit the appropriate multiple instruction...
|
||||
// FIXME: We need to mark that this modified AH, DX, or EDX also!!
|
||||
BuildMI(BB, MulOpcode[Class], 2, Reg).addReg(Reg).addReg(Op1Reg);
|
||||
|
||||
// Put the result into the destination register...
|
||||
BuildMI(BB, MovOpcode[Class], 1, getReg(I)).addReg(Reg);
|
||||
|
||||
}
|
||||
|
||||
/// Shift instructions: 'shl', 'sar', 'shr' - Some special cases here
|
||||
/// for constant immediate shift values, and for constant immediate
|
||||
@ -269,7 +296,7 @@ ISel::visitShiftInst (ShiftInst & I)
|
||||
//
|
||||
|
||||
// Emit: move cl, shiftAmount (put the shift amount in CL.)
|
||||
BuildMI (BB, X86::MOVrr8, 2, X86::CL).addReg(getReg(I.getOperand(1)));
|
||||
BuildMI(BB, X86::MOVrr8, 1, X86::CL).addReg(getReg(I.getOperand(1)));
|
||||
|
||||
// This is a shift right (SHR).
|
||||
static const unsigned NonConstantOperand[][4] = {
|
||||
|
@ -61,6 +61,7 @@ namespace {
|
||||
// Arithmetic operators
|
||||
void visitAdd(BinaryOperator &B) { visitSimpleBinary(B, 0); }
|
||||
void visitSub(BinaryOperator &B) { visitSimpleBinary(B, 1); }
|
||||
void visitMul(BinaryOperator &B);
|
||||
|
||||
// Bitwise operators
|
||||
void visitAnd(BinaryOperator &B) { visitSimpleBinary(B, 2); }
|
||||
@ -221,7 +222,33 @@ void ISel::visitSimpleBinary(BinaryOperator &B, unsigned OperatorClass) {
|
||||
BuildMI(BB, Opcode, 2, getReg(B)).addReg(Op0r).addReg(Op1r);
|
||||
}
|
||||
|
||||
/// visitMul - Multiplies are not simple binary operators because they must deal
|
||||
/// with the EAX register explicitly.
|
||||
///
|
||||
void ISel::visitMul(BinaryOperator &I) {
|
||||
unsigned Class = getClass(I.getType());
|
||||
if (Class > 2) // FIXME: Handle longs
|
||||
visitInstruction(I);
|
||||
|
||||
static const unsigned Regs[] ={ X86::AL , X86::AX , X86::EAX };
|
||||
static const unsigned MulOpcode[]={ X86::MULrr8, X86::MULrr16, X86::MULrr32 };
|
||||
static const unsigned MovOpcode[]={ X86::MOVrr8, X86::MOVrr16, X86::MOVrr32 };
|
||||
|
||||
unsigned Reg = Regs[Class];
|
||||
unsigned Op0Reg = getReg(I.getOperand(1));
|
||||
unsigned Op1Reg = getReg(I.getOperand(1));
|
||||
|
||||
// Put the first operand into one of the A registers...
|
||||
BuildMI(BB, MovOpcode[Class], 1, Reg).addReg(Op0Reg);
|
||||
|
||||
// Emit the appropriate multiple instruction...
|
||||
// FIXME: We need to mark that this modified AH, DX, or EDX also!!
|
||||
BuildMI(BB, MulOpcode[Class], 2, Reg).addReg(Reg).addReg(Op1Reg);
|
||||
|
||||
// Put the result into the destination register...
|
||||
BuildMI(BB, MovOpcode[Class], 1, getReg(I)).addReg(Reg);
|
||||
|
||||
}
|
||||
|
||||
/// Shift instructions: 'shl', 'sar', 'shr' - Some special cases here
|
||||
/// for constant immediate shift values, and for constant immediate
|
||||
@ -269,7 +296,7 @@ ISel::visitShiftInst (ShiftInst & I)
|
||||
//
|
||||
|
||||
// Emit: move cl, shiftAmount (put the shift amount in CL.)
|
||||
BuildMI (BB, X86::MOVrr8, 2, X86::CL).addReg(getReg(I.getOperand(1)));
|
||||
BuildMI(BB, X86::MOVrr8, 1, X86::CL).addReg(getReg(I.getOperand(1)));
|
||||
|
||||
// This is a shift right (SHR).
|
||||
static const unsigned NonConstantOperand[][4] = {
|
||||
|
@ -52,6 +52,10 @@ I(ADDrr32 , "addl", 0, 0) // R32 += R32 01/r
|
||||
I(SUBrr8 , "subb", 0, 0) // R8 -= R8 2A/r
|
||||
I(SUBrr16 , "subw", 0, 0) // R16 -= R16 2B/r
|
||||
I(SUBrr32 , "subl", 0, 0) // R32 -= R32 2B/r
|
||||
I(MULrr8 , "mulb", 0, 0) // AX = AL*R8 F6/4
|
||||
I(MULrr16 , "mulw", 0, 0) // DX:AX= AX*R16 F7/4
|
||||
I(MULrr32 , "mull", 0, 0) // ED:EA= EA*R32 F7/4
|
||||
|
||||
|
||||
// Logical operators
|
||||
I(ANDrr8 , "andb", 0, 0) // R8 &= R8 20/r
|
||||
|
Loading…
Reference in New Issue
Block a user