void Section::Optimize(AsmFile *fil) { AsmExpr::SetSection(this); bool done = false; while (!done) { int pc = 0; done = true; for (int i=0; i < instructions.size(); i++) { if (instructions[i]->IsLabel()) { Label *l = instructions[i]->GetLabel(); if (l) { l->SetOffset(pc); labels[l->GetName()] = pc; } } else { int n = instructions[i]->GetSize() ; instructions[i]->SetOffset(pc); instructions[i]->Optimize(pc, false); int m = instructions[i]->GetSize() ; pc += m; if (n != m) done = false; } } } int pc = 0; for (int i=0; i < instructions.size(); i++) { instructions[i]->Optimize(pc, true); pc += instructions[i]->GetSize(); } }
void AsmFile::DoLabel(std::string &name, int lineno) { NeedSection(); Label *label; if (caseInsensitive) { for (int i=0; i < name.size(); i++) name[i] = toupper(name[i]); } std::string realName = name; bool nl = false; if (name.size() > 2) { if (name[0] == '.' && name[1] == '.' && name[2] == '@') { if (name.size() == 3) throw new std::runtime_error("Malformed non-local label"); nl = true; } } if (!nl && name[0] == '.') { if (name == "..start") { if (startupSection) { throw new std::runtime_error("Multiple start addresses specified"); } label = new Label(name, labels.size(), currentSection->GetSect()); startupSection = currentSection; } else { if (currentLabel) { realName = currentLabel->GetName() + name; } } } if (labels[realName] != NULL) { if (realName != "..start") { throw new std::runtime_error(std::string("Label '") + name + "' already exists."); } } else { if (inAbsolute) { label = new Label(realName, labels.size(), 0); label->SetOffset(absoluteValue); AsmExpr::SetEqu(realName, new AsmExprNode(absoluteValue)); if (lineno >= 0) listing.Add(label, lineno, preProcessor.InMacro()); } else { label = new Label(realName, labels.size(), currentSection->GetSect()-1); } if (name[0] != '.') { currentLabel = label; AsmExpr::SetCurrentLabel(label->GetName()); } thisLabel = label; labels[realName] = label; numericLabels.push_back(label); if (!inAbsolute) currentSection->InsertLabel(label); // if (lineno >= 0) // listing.Add(thisLabel, lineno, preProcessor.InMacro()); if (realName == "..start") startupLabel = label; } if (GetKeyword() == Lexer::colon) { NextToken(); thisLabel = NULL; } }