added new instructions, SUBTRACT, MULTIPLY, DIVICE, BRANCH_*, and RETURN. Changed LoadVar/SaveVar to have uint32 operand. Added optional paramter branchOp to ICodeGenerator::branchConditional() & endWhileExpression() to parametrize branch kind. Added complete(Register) to generate a RETURN instruction.

This commit is contained in:
beard%netscape.com 2000-04-06 02:57:42 +00:00
Родитель 2901700dc5
Коммит a57994c317
4 изменённых файлов: 112 добавлений и 36 удалений

Просмотреть файл

@ -51,17 +51,24 @@ namespace JavaScript {
if ((*ii)->itsOp == BRANCH) if ((*ii)->itsOp == BRANCH)
static_cast<Branch *>(*ii)->itsOperand1 = labels[static_cast<Branch *>(*ii)->itsOperand1]->itsOffset; static_cast<Branch *>(*ii)->itsOperand1 = labels[static_cast<Branch *>(*ii)->itsOperand1]->itsOffset;
else else
if ((*ii)->itsOp == BRANCH_COND) if ((*ii)->itsOp >= BRANCH_LT && (*ii)->itsOp <= BRANCH_GT)
static_cast<BranchCond *>(*ii)->itsOperand1 = labels[static_cast<BranchCond *>(*ii)->itsOperand1]->itsOffset; static_cast<BranchCond *>(*ii)->itsOperand1 = labels[static_cast<BranchCond *>(*ii)->itsOperand1]->itsOffset;
} }
return iCode; return iCode;
} }
InstructionStream *ICodeGenerator::complete(Register result)
{
Return *instr = new Return(RETURN, result);
iCode->push_back(instr);
return complete();
}
/***********************************************************************************************/ /***********************************************************************************************/
Register ICodeGenerator::loadVariable(int32 frameIndex) Register ICodeGenerator::loadVariable(uint32 frameIndex)
{ {
Register dest = getRegister(); Register dest = getRegister();
LoadVar *instr = new LoadVar(LOAD_VAR, frameIndex, dest); LoadVar *instr = new LoadVar(LOAD_VAR, frameIndex, dest);
@ -93,7 +100,7 @@ namespace JavaScript {
return dest; return dest;
} }
void ICodeGenerator::saveVariable(int32 frameIndex, Register value) void ICodeGenerator::saveVariable(uint32 frameIndex, Register value)
{ {
SaveVar *instr = new SaveVar(SAVE_VAR, frameIndex, value); SaveVar *instr = new SaveVar(SAVE_VAR, frameIndex, value);
iCode->push_back(instr); iCode->push_back(instr);
@ -121,9 +128,9 @@ namespace JavaScript {
iCode->push_back(instr); iCode->push_back(instr);
} }
void ICodeGenerator::branchConditional(int32 label, Register condition) void ICodeGenerator::branchConditional(int32 label, Register condition, ICodeOp branchOp)
{ {
BranchCond *instr = new BranchCond(BRANCH_COND, label, condition); BranchCond *instr = new BranchCond(branchOp, label, condition);
iCode->push_back(instr); iCode->push_back(instr);
} }
@ -204,12 +211,12 @@ namespace JavaScript {
iCode = new InstructionStream(); iCode = new InstructionStream();
} }
void ICodeGenerator::endWhileExpression(Register condition) void ICodeGenerator::endWhileExpression(Register condition, ICodeOp branchOp)
{ {
WhileCodeState *ics = static_cast<WhileCodeState *>(stitcher.back()); WhileCodeState *ics = static_cast<WhileCodeState *>(stitcher.back());
ASSERT(ics->stateKind == While_state); ASSERT(ics->stateKind == While_state);
branchConditional(ics->whileBody, condition); branchConditional(ics->whileBody, condition, branchOp);
resetTopRegister(); resetTopRegister();
// stash away the condition expression and switch // stash away the condition expression and switch
// back to the main stream // back to the main stream
@ -530,10 +537,19 @@ namespace JavaScript {
"get_prop", "get_prop",
"set_prop", "set_prop",
"add", "add",
"subtract",
"multiply",
"divide",
"compare", "compare",
"not", "not",
"branch", "branch",
"branch_cond", "branch_lt",
"branch_le",
"branch_eq",
"branch_ne",
"branch_ge",
"branch_gt",
"return"
}; };
ostream &operator<<(ostream &s, StringAtom &str) ostream &operator<<(ostream &s, StringAtom &str)
@ -580,7 +596,12 @@ namespace JavaScript {
s << "target #" << t->itsOperand1; s << "target #" << t->itsOperand1;
} }
break; break;
case BRANCH_COND : case BRANCH_LT :
case BRANCH_LE :
case BRANCH_EQ :
case BRANCH_NE :
case BRANCH_GE :
case BRANCH_GT :
{ {
BranchCond *t = static_cast<BranchCond * >(instr); BranchCond *t = static_cast<BranchCond * >(instr);
s << "target #" << t->itsOperand1 << ", R" << t->itsOperand2; s << "target #" << t->itsOperand1 << ", R" << t->itsOperand2;
@ -600,6 +621,12 @@ namespace JavaScript {
s << "R" << t->itsOperand1 << ", R" << t->itsOperand2; s << "R" << t->itsOperand1 << ", R" << t->itsOperand2;
} }
break; break;
case RETURN :
{
Return *t = static_cast<Return * >(instr);
s << "R" << t->itsOperand1;
}
break;
} }
s << "\n"; s << "\n";
} }
@ -612,6 +639,3 @@ namespace JavaScript {
} // namespace JavaScript } // namespace JavaScript

Просмотреть файл

@ -48,11 +48,23 @@ namespace JavaScript {
SET_PROP, // StringAtom & Base Register Source Register SET_PROP, // StringAtom & Base Register Source Register
ADD, // Source Register 1 Source Register 2 Destination Register ADD, // Source Register 1 Source Register 2 Destination Register
SUBTRACT,
MULTIPLY,
DIVIDE,
COMPARE, // Source Register 1 Source Register 2 Destination Register COMPARE, // Source Register 1 Source Register 2 Destination Register
NOT, // Source Register Destination Register NOT, // Source Register Destination Register
BRANCH, // Target label BRANCH, // Target label
BRANCH_COND // Target label Condition Register
BRANCH_LT, // Target label Condition Register
BRANCH_LE,
BRANCH_EQ,
BRANCH_NE,
BRANCH_GE,
BRANCH_GT,
RETURN // Source Register
}; };
class Instruction { class Instruction {
@ -103,11 +115,12 @@ namespace JavaScript {
typedef Instruction_3<StringAtom*, Register, Register> SetProp; typedef Instruction_3<StringAtom*, Register, Register> SetProp;
typedef Instruction_2<StringAtom*, Register> LoadName, SaveName; typedef Instruction_2<StringAtom*, Register> LoadName, SaveName;
typedef Instruction_2<float64, Register> LoadImmediate; typedef Instruction_2<float64, Register> LoadImmediate;
typedef Instruction_2<int32, Register> LoadVar, SaveVar; typedef Instruction_2<uint32, Register> LoadVar, SaveVar;
typedef Instruction_1<int32> Branch; typedef Instruction_1<int32> Branch;
typedef Instruction_2<int32, Register> BranchCond; typedef Instruction_2<int32, Register> BranchCond;
typedef Instruction_3<Register, Register, Register> Arithmetic; typedef Instruction_3<Register, Register, Register> Arithmetic;
typedef Instruction_2<Register, Register> Move; typedef Instruction_2<Register, Register> Move;
typedef Instruction_1<Register> Return;
typedef std::vector<Instruction *> InstructionStream; typedef std::vector<Instruction *> InstructionStream;
typedef InstructionStream::iterator InstructionIterator; typedef InstructionStream::iterator InstructionIterator;
@ -172,7 +185,7 @@ namespace JavaScript {
void setLabel(InstructionStream *stream, int32 label); void setLabel(InstructionStream *stream, int32 label);
void branch(int32 label); void branch(int32 label);
void branchConditional(int32 label, Register condition); void branchConditional(int32 label, Register condition, ICodeOp branchOp = BRANCH_NE);
public: public:
ICodeGenerator() : topRegister(0) { iCode = new InstructionStream(); } ICodeGenerator() : topRegister(0) { iCode = new InstructionStream(); }
@ -180,16 +193,17 @@ namespace JavaScript {
void mergeStream(InstructionStream *sideStream); void mergeStream(InstructionStream *sideStream);
InstructionStream *complete(); InstructionStream *complete();
InstructionStream *complete(Register result);
ostream &print(ostream &s); ostream &print(ostream &s);
Register op(ICodeOp op, Register source); Register op(ICodeOp op, Register source);
Register op(ICodeOp op, Register source1, Register source2); Register op(ICodeOp op, Register source1, Register source2);
Register loadVariable(int32 frameIndex); Register loadVariable(uint32 frameIndex);
Register loadImmediate(double value); Register loadImmediate(double value);
void saveVariable(int32 frameIndex, Register value); void saveVariable(uint32 frameIndex, Register value);
Register loadName(StringAtom &name); Register loadName(StringAtom &name);
Register getProperty(StringAtom &name, Register base); Register getProperty(StringAtom &name, Register base);
@ -210,7 +224,7 @@ namespace JavaScript {
void beginWhileStatement(uint32 pos); void beginWhileStatement(uint32 pos);
void endWhileExpression(Register condition); void endWhileExpression(Register condition, ICodeOp branchOp = BRANCH_NE);
void endWhileStatement(); void endWhileStatement();

Просмотреть файл

@ -51,17 +51,24 @@ namespace JavaScript {
if ((*ii)->itsOp == BRANCH) if ((*ii)->itsOp == BRANCH)
static_cast<Branch *>(*ii)->itsOperand1 = labels[static_cast<Branch *>(*ii)->itsOperand1]->itsOffset; static_cast<Branch *>(*ii)->itsOperand1 = labels[static_cast<Branch *>(*ii)->itsOperand1]->itsOffset;
else else
if ((*ii)->itsOp == BRANCH_COND) if ((*ii)->itsOp >= BRANCH_LT && (*ii)->itsOp <= BRANCH_GT)
static_cast<BranchCond *>(*ii)->itsOperand1 = labels[static_cast<BranchCond *>(*ii)->itsOperand1]->itsOffset; static_cast<BranchCond *>(*ii)->itsOperand1 = labels[static_cast<BranchCond *>(*ii)->itsOperand1]->itsOffset;
} }
return iCode; return iCode;
} }
InstructionStream *ICodeGenerator::complete(Register result)
{
Return *instr = new Return(RETURN, result);
iCode->push_back(instr);
return complete();
}
/***********************************************************************************************/ /***********************************************************************************************/
Register ICodeGenerator::loadVariable(int32 frameIndex) Register ICodeGenerator::loadVariable(uint32 frameIndex)
{ {
Register dest = getRegister(); Register dest = getRegister();
LoadVar *instr = new LoadVar(LOAD_VAR, frameIndex, dest); LoadVar *instr = new LoadVar(LOAD_VAR, frameIndex, dest);
@ -93,7 +100,7 @@ namespace JavaScript {
return dest; return dest;
} }
void ICodeGenerator::saveVariable(int32 frameIndex, Register value) void ICodeGenerator::saveVariable(uint32 frameIndex, Register value)
{ {
SaveVar *instr = new SaveVar(SAVE_VAR, frameIndex, value); SaveVar *instr = new SaveVar(SAVE_VAR, frameIndex, value);
iCode->push_back(instr); iCode->push_back(instr);
@ -121,9 +128,9 @@ namespace JavaScript {
iCode->push_back(instr); iCode->push_back(instr);
} }
void ICodeGenerator::branchConditional(int32 label, Register condition) void ICodeGenerator::branchConditional(int32 label, Register condition, ICodeOp branchOp)
{ {
BranchCond *instr = new BranchCond(BRANCH_COND, label, condition); BranchCond *instr = new BranchCond(branchOp, label, condition);
iCode->push_back(instr); iCode->push_back(instr);
} }
@ -204,12 +211,12 @@ namespace JavaScript {
iCode = new InstructionStream(); iCode = new InstructionStream();
} }
void ICodeGenerator::endWhileExpression(Register condition) void ICodeGenerator::endWhileExpression(Register condition, ICodeOp branchOp)
{ {
WhileCodeState *ics = static_cast<WhileCodeState *>(stitcher.back()); WhileCodeState *ics = static_cast<WhileCodeState *>(stitcher.back());
ASSERT(ics->stateKind == While_state); ASSERT(ics->stateKind == While_state);
branchConditional(ics->whileBody, condition); branchConditional(ics->whileBody, condition, branchOp);
resetTopRegister(); resetTopRegister();
// stash away the condition expression and switch // stash away the condition expression and switch
// back to the main stream // back to the main stream
@ -530,10 +537,19 @@ namespace JavaScript {
"get_prop", "get_prop",
"set_prop", "set_prop",
"add", "add",
"subtract",
"multiply",
"divide",
"compare", "compare",
"not", "not",
"branch", "branch",
"branch_cond", "branch_lt",
"branch_le",
"branch_eq",
"branch_ne",
"branch_ge",
"branch_gt",
"return"
}; };
ostream &operator<<(ostream &s, StringAtom &str) ostream &operator<<(ostream &s, StringAtom &str)
@ -580,7 +596,12 @@ namespace JavaScript {
s << "target #" << t->itsOperand1; s << "target #" << t->itsOperand1;
} }
break; break;
case BRANCH_COND : case BRANCH_LT :
case BRANCH_LE :
case BRANCH_EQ :
case BRANCH_NE :
case BRANCH_GE :
case BRANCH_GT :
{ {
BranchCond *t = static_cast<BranchCond * >(instr); BranchCond *t = static_cast<BranchCond * >(instr);
s << "target #" << t->itsOperand1 << ", R" << t->itsOperand2; s << "target #" << t->itsOperand1 << ", R" << t->itsOperand2;
@ -600,6 +621,12 @@ namespace JavaScript {
s << "R" << t->itsOperand1 << ", R" << t->itsOperand2; s << "R" << t->itsOperand1 << ", R" << t->itsOperand2;
} }
break; break;
case RETURN :
{
Return *t = static_cast<Return * >(instr);
s << "R" << t->itsOperand1;
}
break;
} }
s << "\n"; s << "\n";
} }
@ -612,6 +639,3 @@ namespace JavaScript {
} // namespace JavaScript } // namespace JavaScript

Просмотреть файл

@ -48,11 +48,23 @@ namespace JavaScript {
SET_PROP, // StringAtom & Base Register Source Register SET_PROP, // StringAtom & Base Register Source Register
ADD, // Source Register 1 Source Register 2 Destination Register ADD, // Source Register 1 Source Register 2 Destination Register
SUBTRACT,
MULTIPLY,
DIVIDE,
COMPARE, // Source Register 1 Source Register 2 Destination Register COMPARE, // Source Register 1 Source Register 2 Destination Register
NOT, // Source Register Destination Register NOT, // Source Register Destination Register
BRANCH, // Target label BRANCH, // Target label
BRANCH_COND // Target label Condition Register
BRANCH_LT, // Target label Condition Register
BRANCH_LE,
BRANCH_EQ,
BRANCH_NE,
BRANCH_GE,
BRANCH_GT,
RETURN // Source Register
}; };
class Instruction { class Instruction {
@ -103,11 +115,12 @@ namespace JavaScript {
typedef Instruction_3<StringAtom*, Register, Register> SetProp; typedef Instruction_3<StringAtom*, Register, Register> SetProp;
typedef Instruction_2<StringAtom*, Register> LoadName, SaveName; typedef Instruction_2<StringAtom*, Register> LoadName, SaveName;
typedef Instruction_2<float64, Register> LoadImmediate; typedef Instruction_2<float64, Register> LoadImmediate;
typedef Instruction_2<int32, Register> LoadVar, SaveVar; typedef Instruction_2<uint32, Register> LoadVar, SaveVar;
typedef Instruction_1<int32> Branch; typedef Instruction_1<int32> Branch;
typedef Instruction_2<int32, Register> BranchCond; typedef Instruction_2<int32, Register> BranchCond;
typedef Instruction_3<Register, Register, Register> Arithmetic; typedef Instruction_3<Register, Register, Register> Arithmetic;
typedef Instruction_2<Register, Register> Move; typedef Instruction_2<Register, Register> Move;
typedef Instruction_1<Register> Return;
typedef std::vector<Instruction *> InstructionStream; typedef std::vector<Instruction *> InstructionStream;
typedef InstructionStream::iterator InstructionIterator; typedef InstructionStream::iterator InstructionIterator;
@ -172,7 +185,7 @@ namespace JavaScript {
void setLabel(InstructionStream *stream, int32 label); void setLabel(InstructionStream *stream, int32 label);
void branch(int32 label); void branch(int32 label);
void branchConditional(int32 label, Register condition); void branchConditional(int32 label, Register condition, ICodeOp branchOp = BRANCH_NE);
public: public:
ICodeGenerator() : topRegister(0) { iCode = new InstructionStream(); } ICodeGenerator() : topRegister(0) { iCode = new InstructionStream(); }
@ -180,16 +193,17 @@ namespace JavaScript {
void mergeStream(InstructionStream *sideStream); void mergeStream(InstructionStream *sideStream);
InstructionStream *complete(); InstructionStream *complete();
InstructionStream *complete(Register result);
ostream &print(ostream &s); ostream &print(ostream &s);
Register op(ICodeOp op, Register source); Register op(ICodeOp op, Register source);
Register op(ICodeOp op, Register source1, Register source2); Register op(ICodeOp op, Register source1, Register source2);
Register loadVariable(int32 frameIndex); Register loadVariable(uint32 frameIndex);
Register loadImmediate(double value); Register loadImmediate(double value);
void saveVariable(int32 frameIndex, Register value); void saveVariable(uint32 frameIndex, Register value);
Register loadName(StringAtom &name); Register loadName(StringAtom &name);
Register getProperty(StringAtom &name, Register base); Register getProperty(StringAtom &name, Register base);
@ -210,7 +224,7 @@ namespace JavaScript {
void beginWhileStatement(uint32 pos); void beginWhileStatement(uint32 pos);
void endWhileExpression(Register condition); void endWhileExpression(Register condition, ICodeOp branchOp = BRANCH_NE);
void endWhileStatement(); void endWhileStatement();