mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
Make labels work in asm blocks; allow labels as
parameters. Rename ValueRefList to ParamList in AsmParser, since its only use is for parameters. llvm-svn: 43734
This commit is contained in:
parent
dbc286177c
commit
1f70f86c7a
@ -241,12 +241,12 @@ struct ArgListEntry {
|
|||||||
|
|
||||||
typedef std::vector<struct ArgListEntry> ArgListType;
|
typedef std::vector<struct ArgListEntry> ArgListType;
|
||||||
|
|
||||||
struct ValueRefListEntry {
|
struct ParamListEntry {
|
||||||
Value *Val;
|
Value *Val;
|
||||||
uint16_t Attrs;
|
uint16_t Attrs;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<ValueRefListEntry> ValueRefList;
|
typedef std::vector<ParamListEntry> ParamList;
|
||||||
|
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -14,7 +14,7 @@ typedef union {
|
|||||||
llvm::ArgListType *ArgList;
|
llvm::ArgListType *ArgList;
|
||||||
llvm::TypeWithAttrs TypeWithAttrs;
|
llvm::TypeWithAttrs TypeWithAttrs;
|
||||||
llvm::TypeWithAttrsList *TypeWithAttrsList;
|
llvm::TypeWithAttrsList *TypeWithAttrsList;
|
||||||
llvm::ValueRefList *ValueRefList;
|
llvm::ParamList *ParamList;
|
||||||
|
|
||||||
// Represent the RHS of PHI node
|
// Represent the RHS of PHI node
|
||||||
std::list<std::pair<llvm::Value*,
|
std::list<std::pair<llvm::Value*,
|
||||||
|
@ -981,7 +981,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
|
|||||||
llvm::ArgListType *ArgList;
|
llvm::ArgListType *ArgList;
|
||||||
llvm::TypeWithAttrs TypeWithAttrs;
|
llvm::TypeWithAttrs TypeWithAttrs;
|
||||||
llvm::TypeWithAttrsList *TypeWithAttrsList;
|
llvm::TypeWithAttrsList *TypeWithAttrsList;
|
||||||
llvm::ValueRefList *ValueRefList;
|
llvm::ParamList *ParamList;
|
||||||
|
|
||||||
// Represent the RHS of PHI node
|
// Represent the RHS of PHI node
|
||||||
std::list<std::pair<llvm::Value*,
|
std::list<std::pair<llvm::Value*,
|
||||||
@ -1021,7 +1021,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
|
|||||||
%type <ConstVector> ConstVector
|
%type <ConstVector> ConstVector
|
||||||
%type <ArgList> ArgList ArgListH
|
%type <ArgList> ArgList ArgListH
|
||||||
%type <PHIList> PHIList
|
%type <PHIList> PHIList
|
||||||
%type <ValueRefList> ValueRefList // For call param lists & GEP indices
|
%type <ParamList> ParamList // For call param lists & GEP indices
|
||||||
%type <ValueList> IndexList // For GEP indices
|
%type <ValueList> IndexList // For GEP indices
|
||||||
%type <TypeList> TypeListI
|
%type <TypeList> TypeListI
|
||||||
%type <TypeWithAttrsList> ArgTypeList ArgTypeListI
|
%type <TypeWithAttrsList> ArgTypeList ArgTypeListI
|
||||||
@ -2609,7 +2609,7 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result...
|
|||||||
$$ = S;
|
$$ = S;
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
}
|
}
|
||||||
| INVOKE OptCallingConv ResultTypes ValueRef '(' ValueRefList ')' OptFuncAttrs
|
| INVOKE OptCallingConv ResultTypes ValueRef '(' ParamList ')' OptFuncAttrs
|
||||||
TO LABEL ValueRef UNWIND LABEL ValueRef {
|
TO LABEL ValueRef UNWIND LABEL ValueRef {
|
||||||
|
|
||||||
// Handle the short syntax
|
// Handle the short syntax
|
||||||
@ -2624,7 +2624,7 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result...
|
|||||||
ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = $8;
|
ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = $8;
|
||||||
Attrs.push_back(PAWI);
|
Attrs.push_back(PAWI);
|
||||||
}
|
}
|
||||||
ValueRefList::iterator I = $6->begin(), E = $6->end();
|
ParamList::iterator I = $6->begin(), E = $6->end();
|
||||||
unsigned index = 1;
|
unsigned index = 1;
|
||||||
for (; I != E; ++I, ++index) {
|
for (; I != E; ++I, ++index) {
|
||||||
const Type *Ty = I->Val->getType();
|
const Type *Ty = I->Val->getType();
|
||||||
@ -2665,7 +2665,7 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result...
|
|||||||
// correctly!
|
// correctly!
|
||||||
FunctionType::param_iterator I = Ty->param_begin();
|
FunctionType::param_iterator I = Ty->param_begin();
|
||||||
FunctionType::param_iterator E = Ty->param_end();
|
FunctionType::param_iterator E = Ty->param_end();
|
||||||
ValueRefList::iterator ArgI = $6->begin(), ArgE = $6->end();
|
ParamList::iterator ArgI = $6->begin(), ArgE = $6->end();
|
||||||
|
|
||||||
for (; ArgI != ArgE && I != E; ++ArgI, ++I) {
|
for (; ArgI != ArgE && I != E; ++ArgI, ++I) {
|
||||||
if (ArgI->Val->getType() != *I)
|
if (ArgI->Val->getType() != *I)
|
||||||
@ -2755,25 +2755,37 @@ PHIList : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
ValueRefList : Types ValueRef OptParamAttrs {
|
ParamList : Types ValueRef OptParamAttrs {
|
||||||
if (!UpRefs.empty())
|
if (!UpRefs.empty())
|
||||||
GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
|
GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
|
||||||
// Used for call and invoke instructions
|
// Used for call and invoke instructions
|
||||||
$$ = new ValueRefList();
|
$$ = new ParamList();
|
||||||
ValueRefListEntry E; E.Attrs = $3; E.Val = getVal($1->get(), $2);
|
ParamListEntry E; E.Attrs = $3; E.Val = getVal($1->get(), $2);
|
||||||
$$->push_back(E);
|
$$->push_back(E);
|
||||||
delete $1;
|
delete $1;
|
||||||
}
|
}
|
||||||
| ValueRefList ',' Types ValueRef OptParamAttrs {
|
| LABEL ValueRef OptParamAttrs {
|
||||||
|
// Labels are only valid in ASMs
|
||||||
|
$$ = new ParamList();
|
||||||
|
ParamListEntry E; E.Attrs = $3; E.Val = getBBVal($2);
|
||||||
|
$$->push_back(E);
|
||||||
|
}
|
||||||
|
| ParamList ',' Types ValueRef OptParamAttrs {
|
||||||
if (!UpRefs.empty())
|
if (!UpRefs.empty())
|
||||||
GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
|
GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
ValueRefListEntry E; E.Attrs = $5; E.Val = getVal($3->get(), $4);
|
ParamListEntry E; E.Attrs = $5; E.Val = getVal($3->get(), $4);
|
||||||
$$->push_back(E);
|
$$->push_back(E);
|
||||||
delete $3;
|
delete $3;
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
}
|
}
|
||||||
| /*empty*/ { $$ = new ValueRefList(); };
|
| ParamList ',' LABEL ValueRef OptParamAttrs {
|
||||||
|
$$ = $1;
|
||||||
|
ParamListEntry E; E.Attrs = $5; E.Val = getBBVal($4);
|
||||||
|
$$->push_back(E);
|
||||||
|
CHECK_FOR_ERROR
|
||||||
|
}
|
||||||
|
| /*empty*/ { $$ = new ParamList(); };
|
||||||
|
|
||||||
IndexList // Used for gep instructions and constant expressions
|
IndexList // Used for gep instructions and constant expressions
|
||||||
: /*empty*/ { $$ = new std::vector<Value*>(); }
|
: /*empty*/ { $$ = new std::vector<Value*>(); }
|
||||||
@ -2919,7 +2931,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
|||||||
delete $2; // Free the list...
|
delete $2; // Free the list...
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
}
|
}
|
||||||
| OptTailCall OptCallingConv ResultTypes ValueRef '(' ValueRefList ')'
|
| OptTailCall OptCallingConv ResultTypes ValueRef '(' ParamList ')'
|
||||||
OptFuncAttrs {
|
OptFuncAttrs {
|
||||||
|
|
||||||
// Handle the short syntax
|
// Handle the short syntax
|
||||||
@ -2935,7 +2947,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
|||||||
Attrs.push_back(PAWI);
|
Attrs.push_back(PAWI);
|
||||||
}
|
}
|
||||||
unsigned index = 1;
|
unsigned index = 1;
|
||||||
ValueRefList::iterator I = $6->begin(), E = $6->end();
|
ParamList::iterator I = $6->begin(), E = $6->end();
|
||||||
for (; I != E; ++I, ++index) {
|
for (; I != E; ++I, ++index) {
|
||||||
const Type *Ty = I->Val->getType();
|
const Type *Ty = I->Val->getType();
|
||||||
if (Ty == Type::VoidTy)
|
if (Ty == Type::VoidTy)
|
||||||
@ -2980,7 +2992,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
|||||||
//
|
//
|
||||||
FunctionType::param_iterator I = Ty->param_begin();
|
FunctionType::param_iterator I = Ty->param_begin();
|
||||||
FunctionType::param_iterator E = Ty->param_end();
|
FunctionType::param_iterator E = Ty->param_end();
|
||||||
ValueRefList::iterator ArgI = $6->begin(), ArgE = $6->end();
|
ParamList::iterator ArgI = $6->begin(), ArgE = $6->end();
|
||||||
|
|
||||||
for (; ArgI != ArgE && I != E; ++ArgI, ++I) {
|
for (; ArgI != ArgE && I != E; ++ArgI, ++I) {
|
||||||
if (ArgI->Val->getType() != *I)
|
if (ArgI->Val->getType() != *I)
|
||||||
|
@ -981,7 +981,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
|
|||||||
llvm::ArgListType *ArgList;
|
llvm::ArgListType *ArgList;
|
||||||
llvm::TypeWithAttrs TypeWithAttrs;
|
llvm::TypeWithAttrs TypeWithAttrs;
|
||||||
llvm::TypeWithAttrsList *TypeWithAttrsList;
|
llvm::TypeWithAttrsList *TypeWithAttrsList;
|
||||||
llvm::ValueRefList *ValueRefList;
|
llvm::ParamList *ParamList;
|
||||||
|
|
||||||
// Represent the RHS of PHI node
|
// Represent the RHS of PHI node
|
||||||
std::list<std::pair<llvm::Value*,
|
std::list<std::pair<llvm::Value*,
|
||||||
@ -1021,7 +1021,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
|
|||||||
%type <ConstVector> ConstVector
|
%type <ConstVector> ConstVector
|
||||||
%type <ArgList> ArgList ArgListH
|
%type <ArgList> ArgList ArgListH
|
||||||
%type <PHIList> PHIList
|
%type <PHIList> PHIList
|
||||||
%type <ValueRefList> ValueRefList // For call param lists & GEP indices
|
%type <ParamList> ParamList // For call param lists & GEP indices
|
||||||
%type <ValueList> IndexList // For GEP indices
|
%type <ValueList> IndexList // For GEP indices
|
||||||
%type <TypeList> TypeListI
|
%type <TypeList> TypeListI
|
||||||
%type <TypeWithAttrsList> ArgTypeList ArgTypeListI
|
%type <TypeWithAttrsList> ArgTypeList ArgTypeListI
|
||||||
@ -2609,7 +2609,7 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result...
|
|||||||
$$ = S;
|
$$ = S;
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
}
|
}
|
||||||
| INVOKE OptCallingConv ResultTypes ValueRef '(' ValueRefList ')' OptFuncAttrs
|
| INVOKE OptCallingConv ResultTypes ValueRef '(' ParamList ')' OptFuncAttrs
|
||||||
TO LABEL ValueRef UNWIND LABEL ValueRef {
|
TO LABEL ValueRef UNWIND LABEL ValueRef {
|
||||||
|
|
||||||
// Handle the short syntax
|
// Handle the short syntax
|
||||||
@ -2624,7 +2624,7 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result...
|
|||||||
ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = $8;
|
ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = $8;
|
||||||
Attrs.push_back(PAWI);
|
Attrs.push_back(PAWI);
|
||||||
}
|
}
|
||||||
ValueRefList::iterator I = $6->begin(), E = $6->end();
|
ParamList::iterator I = $6->begin(), E = $6->end();
|
||||||
unsigned index = 1;
|
unsigned index = 1;
|
||||||
for (; I != E; ++I, ++index) {
|
for (; I != E; ++I, ++index) {
|
||||||
const Type *Ty = I->Val->getType();
|
const Type *Ty = I->Val->getType();
|
||||||
@ -2665,7 +2665,7 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result...
|
|||||||
// correctly!
|
// correctly!
|
||||||
FunctionType::param_iterator I = Ty->param_begin();
|
FunctionType::param_iterator I = Ty->param_begin();
|
||||||
FunctionType::param_iterator E = Ty->param_end();
|
FunctionType::param_iterator E = Ty->param_end();
|
||||||
ValueRefList::iterator ArgI = $6->begin(), ArgE = $6->end();
|
ParamList::iterator ArgI = $6->begin(), ArgE = $6->end();
|
||||||
|
|
||||||
for (; ArgI != ArgE && I != E; ++ArgI, ++I) {
|
for (; ArgI != ArgE && I != E; ++ArgI, ++I) {
|
||||||
if (ArgI->Val->getType() != *I)
|
if (ArgI->Val->getType() != *I)
|
||||||
@ -2755,25 +2755,37 @@ PHIList : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
ValueRefList : Types ValueRef OptParamAttrs {
|
ParamList : Types ValueRef OptParamAttrs {
|
||||||
if (!UpRefs.empty())
|
if (!UpRefs.empty())
|
||||||
GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
|
GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
|
||||||
// Used for call and invoke instructions
|
// Used for call and invoke instructions
|
||||||
$$ = new ValueRefList();
|
$$ = new ParamList();
|
||||||
ValueRefListEntry E; E.Attrs = $3; E.Val = getVal($1->get(), $2);
|
ParamListEntry E; E.Attrs = $3; E.Val = getVal($1->get(), $2);
|
||||||
$$->push_back(E);
|
$$->push_back(E);
|
||||||
delete $1;
|
delete $1;
|
||||||
}
|
}
|
||||||
| ValueRefList ',' Types ValueRef OptParamAttrs {
|
| LABEL ValueRef OptParamAttrs {
|
||||||
|
// Labels are only valid in ASMs
|
||||||
|
$$ = new ParamList();
|
||||||
|
ParamListEntry E; E.Attrs = $3; E.Val = getBBVal($2);
|
||||||
|
$$->push_back(E);
|
||||||
|
}
|
||||||
|
| ParamList ',' Types ValueRef OptParamAttrs {
|
||||||
if (!UpRefs.empty())
|
if (!UpRefs.empty())
|
||||||
GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
|
GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
ValueRefListEntry E; E.Attrs = $5; E.Val = getVal($3->get(), $4);
|
ParamListEntry E; E.Attrs = $5; E.Val = getVal($3->get(), $4);
|
||||||
$$->push_back(E);
|
$$->push_back(E);
|
||||||
delete $3;
|
delete $3;
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
}
|
}
|
||||||
| /*empty*/ { $$ = new ValueRefList(); };
|
| ParamList ',' LABEL ValueRef OptParamAttrs {
|
||||||
|
$$ = $1;
|
||||||
|
ParamListEntry E; E.Attrs = $5; E.Val = getBBVal($4);
|
||||||
|
$$->push_back(E);
|
||||||
|
CHECK_FOR_ERROR
|
||||||
|
}
|
||||||
|
| /*empty*/ { $$ = new ParamList(); };
|
||||||
|
|
||||||
IndexList // Used for gep instructions and constant expressions
|
IndexList // Used for gep instructions and constant expressions
|
||||||
: /*empty*/ { $$ = new std::vector<Value*>(); }
|
: /*empty*/ { $$ = new std::vector<Value*>(); }
|
||||||
@ -2919,7 +2931,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
|||||||
delete $2; // Free the list...
|
delete $2; // Free the list...
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
}
|
}
|
||||||
| OptTailCall OptCallingConv ResultTypes ValueRef '(' ValueRefList ')'
|
| OptTailCall OptCallingConv ResultTypes ValueRef '(' ParamList ')'
|
||||||
OptFuncAttrs {
|
OptFuncAttrs {
|
||||||
|
|
||||||
// Handle the short syntax
|
// Handle the short syntax
|
||||||
@ -2935,7 +2947,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
|||||||
Attrs.push_back(PAWI);
|
Attrs.push_back(PAWI);
|
||||||
}
|
}
|
||||||
unsigned index = 1;
|
unsigned index = 1;
|
||||||
ValueRefList::iterator I = $6->begin(), E = $6->end();
|
ParamList::iterator I = $6->begin(), E = $6->end();
|
||||||
for (; I != E; ++I, ++index) {
|
for (; I != E; ++I, ++index) {
|
||||||
const Type *Ty = I->Val->getType();
|
const Type *Ty = I->Val->getType();
|
||||||
if (Ty == Type::VoidTy)
|
if (Ty == Type::VoidTy)
|
||||||
@ -2980,7 +2992,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
|||||||
//
|
//
|
||||||
FunctionType::param_iterator I = Ty->param_begin();
|
FunctionType::param_iterator I = Ty->param_begin();
|
||||||
FunctionType::param_iterator E = Ty->param_end();
|
FunctionType::param_iterator E = Ty->param_end();
|
||||||
ValueRefList::iterator ArgI = $6->begin(), ArgE = $6->end();
|
ParamList::iterator ArgI = $6->begin(), ArgE = $6->end();
|
||||||
|
|
||||||
for (; ArgI != ArgE && I != E; ++ArgI, ++I) {
|
for (; ArgI != ArgE && I != E; ++ArgI, ++I) {
|
||||||
if (ArgI->Val->getType() != *I)
|
if (ArgI->Val->getType() != *I)
|
||||||
|
@ -1506,7 +1506,10 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
|||||||
SmallVector<Value*, 16> Args;
|
SmallVector<Value*, 16> Args;
|
||||||
// Read the fixed params.
|
// Read the fixed params.
|
||||||
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) {
|
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) {
|
||||||
Args.push_back(getFnValueByID(Record[OpNum], FTy->getParamType(i)));
|
if (FTy->getParamType(i)->getTypeID()==Type::LabelTyID)
|
||||||
|
Args.push_back(getBasicBlock(Record[OpNum]));
|
||||||
|
else
|
||||||
|
Args.push_back(getFnValueByID(Record[OpNum], FTy->getParamType(i)));
|
||||||
if (Args.back() == 0) return Error("Invalid CALL record");
|
if (Args.back() == 0) return Error("Invalid CALL record");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1188,13 +1188,18 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const {
|
|||||||
unsigned OpFlags = MI->getOperand(OpNo).getImmedValue();
|
unsigned OpFlags = MI->getOperand(OpNo).getImmedValue();
|
||||||
++OpNo; // Skip over the ID number.
|
++OpNo; // Skip over the ID number.
|
||||||
|
|
||||||
AsmPrinter *AP = const_cast<AsmPrinter*>(this);
|
if (Modifier[0]=='l') // labels are target independent
|
||||||
if ((OpFlags & 7) == 4 /*ADDR MODE*/) {
|
printBasicBlockLabel(MI->getOperand(OpNo).getMachineBasicBlock(),
|
||||||
Error = AP->PrintAsmMemoryOperand(MI, OpNo, AsmPrinterVariant,
|
false, false);
|
||||||
Modifier[0] ? Modifier : 0);
|
else {
|
||||||
} else {
|
AsmPrinter *AP = const_cast<AsmPrinter*>(this);
|
||||||
Error = AP->PrintAsmOperand(MI, OpNo, AsmPrinterVariant,
|
if ((OpFlags & 7) == 4 /*ADDR MODE*/) {
|
||||||
Modifier[0] ? Modifier : 0);
|
Error = AP->PrintAsmMemoryOperand(MI, OpNo, AsmPrinterVariant,
|
||||||
|
Modifier[0] ? Modifier : 0);
|
||||||
|
} else {
|
||||||
|
Error = AP->PrintAsmOperand(MI, OpNo, AsmPrinterVariant,
|
||||||
|
Modifier[0] ? Modifier : 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Error) {
|
if (Error) {
|
||||||
|
@ -803,10 +803,13 @@ void ScheduleDAG::EmitNode(SDNode *Node, unsigned InstanceNo,
|
|||||||
if (ConstantSDNode *CS =
|
if (ConstantSDNode *CS =
|
||||||
dyn_cast<ConstantSDNode>(Node->getOperand(i))) {
|
dyn_cast<ConstantSDNode>(Node->getOperand(i))) {
|
||||||
MI->addImmOperand(CS->getValue());
|
MI->addImmOperand(CS->getValue());
|
||||||
} else {
|
} else if (GlobalAddressSDNode *GA =
|
||||||
GlobalAddressSDNode *GA =
|
dyn_cast<GlobalAddressSDNode>(Node->getOperand(i))) {
|
||||||
cast<GlobalAddressSDNode>(Node->getOperand(i));
|
|
||||||
MI->addGlobalAddressOperand(GA->getGlobal(), GA->getOffset());
|
MI->addGlobalAddressOperand(GA->getGlobal(), GA->getOffset());
|
||||||
|
} else {
|
||||||
|
BasicBlockSDNode *BB =
|
||||||
|
cast<BasicBlockSDNode>(Node->getOperand(i));
|
||||||
|
MI->addMachineBasicBlockOperand(BB->getBasicBlock());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -3489,31 +3489,37 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If this is an input or an indirect output, process the call argument.
|
// If this is an input or an indirect output, process the call argument.
|
||||||
|
// BasicBlocks are labels, currently appearing only in asm's.
|
||||||
if (OpInfo.CallOperandVal) {
|
if (OpInfo.CallOperandVal) {
|
||||||
OpInfo.CallOperand = getValue(OpInfo.CallOperandVal);
|
if (isa<BasicBlock>(OpInfo.CallOperandVal))
|
||||||
const Type *OpTy = OpInfo.CallOperandVal->getType();
|
OpInfo.CallOperand =
|
||||||
// If this is an indirect operand, the operand is a pointer to the
|
DAG.getBasicBlock(FuncInfo.MBBMap[cast<BasicBlock>(OpInfo.CallOperandVal)]);
|
||||||
// accessed type.
|
else {
|
||||||
if (OpInfo.isIndirect)
|
OpInfo.CallOperand = getValue(OpInfo.CallOperandVal);
|
||||||
OpTy = cast<PointerType>(OpTy)->getElementType();
|
const Type *OpTy = OpInfo.CallOperandVal->getType();
|
||||||
|
// If this is an indirect operand, the operand is a pointer to the
|
||||||
// If OpTy is not a first-class value, it may be a struct/union that we
|
// accessed type.
|
||||||
// can tile with integers.
|
if (OpInfo.isIndirect)
|
||||||
if (!OpTy->isFirstClassType() && OpTy->isSized()) {
|
OpTy = cast<PointerType>(OpTy)->getElementType();
|
||||||
unsigned BitSize = TD->getTypeSizeInBits(OpTy);
|
|
||||||
switch (BitSize) {
|
// If OpTy is not a first-class value, it may be a struct/union that we
|
||||||
default: break;
|
// can tile with integers.
|
||||||
case 1:
|
if (!OpTy->isFirstClassType() && OpTy->isSized()) {
|
||||||
case 8:
|
unsigned BitSize = TD->getTypeSizeInBits(OpTy);
|
||||||
case 16:
|
switch (BitSize) {
|
||||||
case 32:
|
default: break;
|
||||||
case 64:
|
case 1:
|
||||||
OpTy = IntegerType::get(BitSize);
|
case 8:
|
||||||
break;
|
case 16:
|
||||||
|
case 32:
|
||||||
|
case 64:
|
||||||
|
OpTy = IntegerType::get(BitSize);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OpVT = TLI.getValueType(OpTy, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
OpVT = TLI.getValueType(OpTy, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OpInfo.ConstraintVT = OpVT;
|
OpInfo.ConstraintVT = OpVT;
|
||||||
|
@ -1396,10 +1396,15 @@ void TargetLowering::LowerAsmOperandForConstraint(SDOperand Op,
|
|||||||
SelectionDAG &DAG) {
|
SelectionDAG &DAG) {
|
||||||
switch (ConstraintLetter) {
|
switch (ConstraintLetter) {
|
||||||
default: break;
|
default: break;
|
||||||
|
case 'X': // Allows any operand; labels (basic block) use this.
|
||||||
|
if (Op.getOpcode() == ISD::BasicBlock) {
|
||||||
|
Ops.push_back(Op);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// fall through
|
||||||
case 'i': // Simple Integer or Relocatable Constant
|
case 'i': // Simple Integer or Relocatable Constant
|
||||||
case 'n': // Simple Integer
|
case 'n': // Simple Integer
|
||||||
case 's': // Relocatable Constant
|
case 's': { // Relocatable Constant
|
||||||
case 'X': { // Allows any operand.
|
|
||||||
// These operands are interested in values of the form (GV+C), where C may
|
// These operands are interested in values of the form (GV+C), where C may
|
||||||
// be folded in as an offset of GV, or it may be explicitly added. Also, it
|
// be folded in as an offset of GV, or it may be explicitly added. Also, it
|
||||||
// is possible and fine if either GV or C are missing.
|
// is possible and fine if either GV or C are missing.
|
||||||
|
41
test/CodeGen/X86/asm-block-labels.ll
Normal file
41
test/CodeGen/X86/asm-block-labels.ll
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
; RUN: llvm-as < %s | opt -std-compile-opts | llc
|
||||||
|
; ModuleID = 'block12.c'
|
||||||
|
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
|
||||||
|
target triple = "i686-apple-darwin8"
|
||||||
|
|
||||||
|
define void @bar() {
|
||||||
|
entry:
|
||||||
|
br label %"LASM$foo"
|
||||||
|
|
||||||
|
"LASM$foo": ; preds = %entry
|
||||||
|
call void asm sideeffect ".file \22block12.c\22", "~{dirflag},~{fpsr},~{flags}"( )
|
||||||
|
call void asm sideeffect ".line 1", "~{dirflag},~{fpsr},~{flags}"( )
|
||||||
|
call void asm sideeffect "int $$1", "~{dirflag},~{fpsr},~{flags},~{memory}"( )
|
||||||
|
call void asm sideeffect ".file \22block12.c\22", "~{dirflag},~{fpsr},~{flags}"( )
|
||||||
|
call void asm sideeffect ".line 2", "~{dirflag},~{fpsr},~{flags}"( )
|
||||||
|
call void asm sideeffect "brl ${0:l}", "X,~{dirflag},~{fpsr},~{flags},~{memory}"( label %"LASM$foo" )
|
||||||
|
br label %return
|
||||||
|
|
||||||
|
return: ; preds = %"LASM$foo"
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @baz() {
|
||||||
|
entry:
|
||||||
|
call void asm sideeffect ".file \22block12.c\22", "~{dirflag},~{fpsr},~{flags}"( )
|
||||||
|
call void asm sideeffect ".line 3", "~{dirflag},~{fpsr},~{flags}"( )
|
||||||
|
call void asm sideeffect "brl ${0:l}", "X,~{dirflag},~{fpsr},~{flags},~{memory}"( label %"LASM$foo" )
|
||||||
|
call void asm sideeffect ".file \22block12.c\22", "~{dirflag},~{fpsr},~{flags}"( )
|
||||||
|
call void asm sideeffect ".line 4", "~{dirflag},~{fpsr},~{flags}"( )
|
||||||
|
call void asm sideeffect "int $$1", "~{dirflag},~{fpsr},~{flags},~{memory}"( )
|
||||||
|
br label %"LASM$foo"
|
||||||
|
|
||||||
|
"LASM$foo": ; preds = %entry
|
||||||
|
call void asm sideeffect ".file \22block12.c\22", "~{dirflag},~{fpsr},~{flags}"( )
|
||||||
|
call void asm sideeffect ".line 5", "~{dirflag},~{fpsr},~{flags}"( )
|
||||||
|
call void asm sideeffect "int $$1", "~{dirflag},~{fpsr},~{flags},~{memory}"( )
|
||||||
|
br label %return
|
||||||
|
|
||||||
|
return: ; preds = %"LASM$foo"
|
||||||
|
ret void
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user