mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-02-07 07:23:13 +01:00
Fix the problems exposed by the callingconv1.d test case.
The first was that unless otherwise specified, inputs are assumed to be in registers even if they specify a "matching output" that's in memory. While testing that fix, I also ran into a bug causing the generated "matching output" for any input was always the first one instead of the correct one.
This commit is contained in:
@@ -385,18 +385,25 @@ assert(0);
|
||||
for(it i = output_constraints.begin(), e = output_constraints.end(); i != e; ++i, ++n) {
|
||||
// rewrite update constraint to in and out constraints
|
||||
if((*i)[0] == '+') {
|
||||
(*i)[0] = '=';
|
||||
std::string input_constraint;
|
||||
std::stringstream ss;
|
||||
ss << n;
|
||||
ss >> input_constraint;
|
||||
//FIXME: I think multiple inout constraints will mess up the order!
|
||||
input_constraints.push_front(input_constraint);
|
||||
assert(*i == mrw_cns && "What else are we updating except memory?");
|
||||
/* LLVM doesn't support updating operands, so split into an input
|
||||
* and an output operand.
|
||||
*/
|
||||
|
||||
// Change update operand to pure output operand.
|
||||
*i = mw_cns;
|
||||
|
||||
// Add input operand with same value, with original as "matching output".
|
||||
std::ostringstream ss;
|
||||
ss << m_cns << (n + asmblock->outputcount);
|
||||
input_constraints.push_front(ss.str());
|
||||
input_values.push_front(output_values[n]);
|
||||
}
|
||||
llvmOutConstraints += *i;
|
||||
llvmOutConstraints += ",";
|
||||
}
|
||||
asmblock->outputcount += n;
|
||||
|
||||
for(it i = input_constraints.begin(), e = input_constraints.end(); i != e; ++i) {
|
||||
llvmInConstraints += *i;
|
||||
llvmInConstraints += ",";
|
||||
|
||||
@@ -81,6 +81,7 @@ struct IRAsmBlock
|
||||
{
|
||||
std::deque<IRAsmStmt*> s;
|
||||
std::set<std::string> clobs;
|
||||
size_t outputcount;
|
||||
|
||||
// stores the labels within the asm block
|
||||
std::vector<Identifier*> internalLabels;
|
||||
@@ -92,7 +93,9 @@ struct IRAsmBlock
|
||||
LLValue* (*retfixup)(IRBuilderHelper b, LLValue* orig); // Modifies retval
|
||||
|
||||
IRAsmBlock(AsmBlockStatement* b)
|
||||
: asmBlock(b), retty(NULL), retn(0), retemu(false), retfixup(NULL) {}
|
||||
: asmBlock(b), retty(NULL), retn(0), retemu(false), retfixup(NULL),
|
||||
outputcount(0)
|
||||
{}
|
||||
};
|
||||
|
||||
// llvm::CallInst and llvm::InvokeInst don't share a common base
|
||||
|
||||
Reference in New Issue
Block a user