mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-25 13:24:46 +00:00
PR400 work phase 1. Add attributed load/store instructions for volatile/align to LLVM.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36349 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -831,13 +831,31 @@ void BytecodeReader::ParseInstruction(SmallVector<unsigned, 8> &Oprnds,
|
||||
&Idx[0], Idx.size());
|
||||
break;
|
||||
}
|
||||
case 62: // volatile load
|
||||
case 62: { // attributed load
|
||||
if (Oprnds.size() != 2 || !isa<PointerType>(InstTy))
|
||||
error("Invalid attributed load instruction!");
|
||||
signed Log2AlignVal = ((Oprnds[1]>>1)-1);
|
||||
Result = new LoadInst(getValue(iType, Oprnds[0]), "", (Oprnds[1] & 1),
|
||||
((Log2AlignVal < 0) ? 0 : 1<<Log2AlignVal));
|
||||
break;
|
||||
}
|
||||
case Instruction::Load:
|
||||
if (Oprnds.size() != 1 || !isa<PointerType>(InstTy))
|
||||
error("Invalid load instruction!");
|
||||
Result = new LoadInst(getValue(iType, Oprnds[0]), "", Opcode == 62);
|
||||
Result = new LoadInst(getValue(iType, Oprnds[0]), "");
|
||||
break;
|
||||
case 63: // volatile store
|
||||
case 63: { // attributed store
|
||||
if (!isa<PointerType>(InstTy) || Oprnds.size() != 3)
|
||||
error("Invalid attributed store instruction!");
|
||||
|
||||
Value *Ptr = getValue(iType, Oprnds[1]);
|
||||
const Type *ValTy = cast<PointerType>(Ptr->getType())->getElementType();
|
||||
signed Log2AlignVal = ((Oprnds[2]>>1)-1);
|
||||
Result = new StoreInst(getValue(getTypeSlot(ValTy), Oprnds[0]), Ptr,
|
||||
(Oprnds[2] & 1),
|
||||
((Log2AlignVal < 0) ? 0 : 1<<Log2AlignVal));
|
||||
break;
|
||||
}
|
||||
case Instruction::Store: {
|
||||
if (!isa<PointerType>(InstTy) || Oprnds.size() != 2)
|
||||
error("Invalid store instruction!");
|
||||
|
@@ -445,7 +445,8 @@ void BytecodeWriter::outputInstructionFormat0(const Instruction *I,
|
||||
unsigned NumArgs = I->getNumOperands();
|
||||
bool HasExtraArg = false;
|
||||
if (isa<CastInst>(I) || isa<InvokeInst>(I) ||
|
||||
isa<CmpInst>(I) || isa<VAArgInst>(I) || Opcode == 58)
|
||||
isa<CmpInst>(I) || isa<VAArgInst>(I) || Opcode == 58 ||
|
||||
Opcode == 62 || Opcode == 63)
|
||||
HasExtraArg = true;
|
||||
if (const AllocationInst *AI = dyn_cast<AllocationInst>(I))
|
||||
HasExtraArg = AI->getAlignment() != 0;
|
||||
@@ -468,6 +469,12 @@ void BytecodeWriter::outputInstructionFormat0(const Instruction *I,
|
||||
} else if (const AllocationInst *AI = dyn_cast<AllocationInst>(I)) {
|
||||
if (AI->getAlignment())
|
||||
output_vbr((unsigned)Log2_32(AI->getAlignment())+1);
|
||||
} else if (Opcode == 62) { // Attributed load
|
||||
output_vbr((unsigned)(((Log2_32(cast<LoadInst>(I)->getAlignment())+1)<<1)
|
||||
+ (cast<LoadInst>(I)->isVolatile() ? 1 : 0)));
|
||||
} else if (Opcode == 63) { // Attributed store
|
||||
output_vbr((unsigned)(((Log2_32(cast<StoreInst>(I)->getAlignment())+1)<<1)
|
||||
+ (cast<StoreInst>(I)->isVolatile() ? 1 : 0)));
|
||||
}
|
||||
} else {
|
||||
output_vbr(Table.getSlot(I->getOperand(0)));
|
||||
@@ -616,7 +623,7 @@ void BytecodeWriter::outputInstruction(const Instruction &I) {
|
||||
unsigned Opcode = I.getOpcode();
|
||||
unsigned NumOperands = I.getNumOperands();
|
||||
|
||||
// Encode 'tail call' as 61, 'volatile load' as 62, and 'volatile store' as
|
||||
// Encode 'tail call' as 61
|
||||
// 63.
|
||||
if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
|
||||
if (CI->getCallingConv() == CallingConv::C) {
|
||||
@@ -632,10 +639,6 @@ void BytecodeWriter::outputInstruction(const Instruction &I) {
|
||||
} else {
|
||||
Opcode = 58; // Call escape sequence.
|
||||
}
|
||||
} else if (isa<LoadInst>(I) && cast<LoadInst>(I).isVolatile()) {
|
||||
Opcode = 62;
|
||||
} else if (isa<StoreInst>(I) && cast<StoreInst>(I).isVolatile()) {
|
||||
Opcode = 63;
|
||||
}
|
||||
|
||||
// Figure out which type to encode with the instruction. Typically we want
|
||||
@@ -744,6 +747,32 @@ void BytecodeWriter::outputInstruction(const Instruction &I) {
|
||||
} else if (isa<InvokeInst>(I)) {
|
||||
// Invoke escape seq has at least 4 operands to encode.
|
||||
++NumOperands;
|
||||
} else if (const LoadInst *LI = dyn_cast<LoadInst>(&I)) {
|
||||
// Encode attributed load as opcode 62
|
||||
// We need to encode the attributes of the load instruction as the second
|
||||
// operand. Its not really a slot, but we don't want to break the
|
||||
// instruction format for these instructions.
|
||||
if (LI->getAlignment() || LI->isVolatile()) {
|
||||
NumOperands = 2;
|
||||
Slots[1] = ((Log2_32(LI->getAlignment())+1)<<1) +
|
||||
(LI->isVolatile() ? 1 : 0);
|
||||
if (Slots[1] > MaxOpSlot)
|
||||
MaxOpSlot = Slots[1];
|
||||
Opcode = 62;
|
||||
}
|
||||
} else if (const StoreInst *SI = dyn_cast<StoreInst>(&I)) {
|
||||
// Encode attributed store as opcode 63
|
||||
// We need to encode the attributes of the store instruction as the third
|
||||
// operand. Its not really a slot, but we don't want to break the
|
||||
// instruction format for these instructions.
|
||||
if (SI->getAlignment() || SI->isVolatile()) {
|
||||
NumOperands = 3;
|
||||
Slots[2] = ((Log2_32(SI->getAlignment())+1)<<1) +
|
||||
(SI->isVolatile() ? 1 : 0);
|
||||
if (Slots[2] > MaxOpSlot)
|
||||
MaxOpSlot = Slots[2];
|
||||
Opcode = 63;
|
||||
}
|
||||
}
|
||||
|
||||
// Decide which instruction encoding to use. This is determined primarily
|
||||
|
Reference in New Issue
Block a user