From a57994c3171e1e5523451680b429e850167ed2a0 Mon Sep 17 00:00:00 2001 From: "beard%netscape.com" Date: Thu, 6 Apr 2000 02:57:42 +0000 Subject: [PATCH] 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. --- js/js2/icodegenerator.cpp | 48 ++++++++++++++++++++++++++++---------- js/js2/icodegenerator.h | 26 ++++++++++++++++----- js2/src/icodegenerator.cpp | 48 ++++++++++++++++++++++++++++---------- js2/src/icodegenerator.h | 26 ++++++++++++++++----- 4 files changed, 112 insertions(+), 36 deletions(-) diff --git a/js/js2/icodegenerator.cpp b/js/js2/icodegenerator.cpp index ebcd4c074d7..e141ca8d4e0 100644 --- a/js/js2/icodegenerator.cpp +++ b/js/js2/icodegenerator.cpp @@ -51,17 +51,24 @@ namespace JavaScript { if ((*ii)->itsOp == BRANCH) static_cast(*ii)->itsOperand1 = labels[static_cast(*ii)->itsOperand1]->itsOffset; else - if ((*ii)->itsOp == BRANCH_COND) + if ((*ii)->itsOp >= BRANCH_LT && (*ii)->itsOp <= BRANCH_GT) static_cast(*ii)->itsOperand1 = labels[static_cast(*ii)->itsOperand1]->itsOffset; } 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(); LoadVar *instr = new LoadVar(LOAD_VAR, frameIndex, dest); @@ -93,7 +100,7 @@ namespace JavaScript { return dest; } - void ICodeGenerator::saveVariable(int32 frameIndex, Register value) + void ICodeGenerator::saveVariable(uint32 frameIndex, Register value) { SaveVar *instr = new SaveVar(SAVE_VAR, frameIndex, value); iCode->push_back(instr); @@ -121,9 +128,9 @@ namespace JavaScript { 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); } @@ -204,12 +211,12 @@ namespace JavaScript { iCode = new InstructionStream(); } - void ICodeGenerator::endWhileExpression(Register condition) + void ICodeGenerator::endWhileExpression(Register condition, ICodeOp branchOp) { WhileCodeState *ics = static_cast(stitcher.back()); ASSERT(ics->stateKind == While_state); - branchConditional(ics->whileBody, condition); + branchConditional(ics->whileBody, condition, branchOp); resetTopRegister(); // stash away the condition expression and switch // back to the main stream @@ -530,10 +537,19 @@ namespace JavaScript { "get_prop", "set_prop", "add", + "subtract", + "multiply", + "divide", "compare", "not", "branch", - "branch_cond", + "branch_lt", + "branch_le", + "branch_eq", + "branch_ne", + "branch_ge", + "branch_gt", + "return" }; ostream &operator<<(ostream &s, StringAtom &str) @@ -580,7 +596,12 @@ namespace JavaScript { s << "target #" << t->itsOperand1; } 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(instr); s << "target #" << t->itsOperand1 << ", R" << t->itsOperand2; @@ -600,6 +621,12 @@ namespace JavaScript { s << "R" << t->itsOperand1 << ", R" << t->itsOperand2; } break; + case RETURN : + { + Return *t = static_cast(instr); + s << "R" << t->itsOperand1; + } + break; } s << "\n"; } @@ -612,6 +639,3 @@ namespace JavaScript { } // namespace JavaScript - - - diff --git a/js/js2/icodegenerator.h b/js/js2/icodegenerator.h index 10b32ed9043..1977bca2f93 100644 --- a/js/js2/icodegenerator.h +++ b/js/js2/icodegenerator.h @@ -48,11 +48,23 @@ namespace JavaScript { SET_PROP, // StringAtom & Base Register Source Register ADD, // Source Register 1 Source Register 2 Destination Register + SUBTRACT, + MULTIPLY, + DIVIDE, + COMPARE, // Source Register 1 Source Register 2 Destination Register NOT, // Source Register Destination Register 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 { @@ -103,11 +115,12 @@ namespace JavaScript { typedef Instruction_3 SetProp; typedef Instruction_2 LoadName, SaveName; typedef Instruction_2 LoadImmediate; - typedef Instruction_2 LoadVar, SaveVar; + typedef Instruction_2 LoadVar, SaveVar; typedef Instruction_1 Branch; typedef Instruction_2 BranchCond; typedef Instruction_3 Arithmetic; typedef Instruction_2 Move; + typedef Instruction_1 Return; typedef std::vector InstructionStream; typedef InstructionStream::iterator InstructionIterator; @@ -172,7 +185,7 @@ namespace JavaScript { void setLabel(InstructionStream *stream, int32 label); void branch(int32 label); - void branchConditional(int32 label, Register condition); + void branchConditional(int32 label, Register condition, ICodeOp branchOp = BRANCH_NE); public: ICodeGenerator() : topRegister(0) { iCode = new InstructionStream(); } @@ -180,16 +193,17 @@ namespace JavaScript { void mergeStream(InstructionStream *sideStream); InstructionStream *complete(); + InstructionStream *complete(Register result); ostream &print(ostream &s); Register op(ICodeOp op, Register source); Register op(ICodeOp op, Register source1, Register source2); - Register loadVariable(int32 frameIndex); + Register loadVariable(uint32 frameIndex); Register loadImmediate(double value); - void saveVariable(int32 frameIndex, Register value); + void saveVariable(uint32 frameIndex, Register value); Register loadName(StringAtom &name); Register getProperty(StringAtom &name, Register base); @@ -210,7 +224,7 @@ namespace JavaScript { void beginWhileStatement(uint32 pos); - void endWhileExpression(Register condition); + void endWhileExpression(Register condition, ICodeOp branchOp = BRANCH_NE); void endWhileStatement(); diff --git a/js2/src/icodegenerator.cpp b/js2/src/icodegenerator.cpp index ebcd4c074d7..e141ca8d4e0 100644 --- a/js2/src/icodegenerator.cpp +++ b/js2/src/icodegenerator.cpp @@ -51,17 +51,24 @@ namespace JavaScript { if ((*ii)->itsOp == BRANCH) static_cast(*ii)->itsOperand1 = labels[static_cast(*ii)->itsOperand1]->itsOffset; else - if ((*ii)->itsOp == BRANCH_COND) + if ((*ii)->itsOp >= BRANCH_LT && (*ii)->itsOp <= BRANCH_GT) static_cast(*ii)->itsOperand1 = labels[static_cast(*ii)->itsOperand1]->itsOffset; } 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(); LoadVar *instr = new LoadVar(LOAD_VAR, frameIndex, dest); @@ -93,7 +100,7 @@ namespace JavaScript { return dest; } - void ICodeGenerator::saveVariable(int32 frameIndex, Register value) + void ICodeGenerator::saveVariable(uint32 frameIndex, Register value) { SaveVar *instr = new SaveVar(SAVE_VAR, frameIndex, value); iCode->push_back(instr); @@ -121,9 +128,9 @@ namespace JavaScript { 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); } @@ -204,12 +211,12 @@ namespace JavaScript { iCode = new InstructionStream(); } - void ICodeGenerator::endWhileExpression(Register condition) + void ICodeGenerator::endWhileExpression(Register condition, ICodeOp branchOp) { WhileCodeState *ics = static_cast(stitcher.back()); ASSERT(ics->stateKind == While_state); - branchConditional(ics->whileBody, condition); + branchConditional(ics->whileBody, condition, branchOp); resetTopRegister(); // stash away the condition expression and switch // back to the main stream @@ -530,10 +537,19 @@ namespace JavaScript { "get_prop", "set_prop", "add", + "subtract", + "multiply", + "divide", "compare", "not", "branch", - "branch_cond", + "branch_lt", + "branch_le", + "branch_eq", + "branch_ne", + "branch_ge", + "branch_gt", + "return" }; ostream &operator<<(ostream &s, StringAtom &str) @@ -580,7 +596,12 @@ namespace JavaScript { s << "target #" << t->itsOperand1; } 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(instr); s << "target #" << t->itsOperand1 << ", R" << t->itsOperand2; @@ -600,6 +621,12 @@ namespace JavaScript { s << "R" << t->itsOperand1 << ", R" << t->itsOperand2; } break; + case RETURN : + { + Return *t = static_cast(instr); + s << "R" << t->itsOperand1; + } + break; } s << "\n"; } @@ -612,6 +639,3 @@ namespace JavaScript { } // namespace JavaScript - - - diff --git a/js2/src/icodegenerator.h b/js2/src/icodegenerator.h index 10b32ed9043..1977bca2f93 100644 --- a/js2/src/icodegenerator.h +++ b/js2/src/icodegenerator.h @@ -48,11 +48,23 @@ namespace JavaScript { SET_PROP, // StringAtom & Base Register Source Register ADD, // Source Register 1 Source Register 2 Destination Register + SUBTRACT, + MULTIPLY, + DIVIDE, + COMPARE, // Source Register 1 Source Register 2 Destination Register NOT, // Source Register Destination Register 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 { @@ -103,11 +115,12 @@ namespace JavaScript { typedef Instruction_3 SetProp; typedef Instruction_2 LoadName, SaveName; typedef Instruction_2 LoadImmediate; - typedef Instruction_2 LoadVar, SaveVar; + typedef Instruction_2 LoadVar, SaveVar; typedef Instruction_1 Branch; typedef Instruction_2 BranchCond; typedef Instruction_3 Arithmetic; typedef Instruction_2 Move; + typedef Instruction_1 Return; typedef std::vector InstructionStream; typedef InstructionStream::iterator InstructionIterator; @@ -172,7 +185,7 @@ namespace JavaScript { void setLabel(InstructionStream *stream, int32 label); void branch(int32 label); - void branchConditional(int32 label, Register condition); + void branchConditional(int32 label, Register condition, ICodeOp branchOp = BRANCH_NE); public: ICodeGenerator() : topRegister(0) { iCode = new InstructionStream(); } @@ -180,16 +193,17 @@ namespace JavaScript { void mergeStream(InstructionStream *sideStream); InstructionStream *complete(); + InstructionStream *complete(Register result); ostream &print(ostream &s); Register op(ICodeOp op, Register source); Register op(ICodeOp op, Register source1, Register source2); - Register loadVariable(int32 frameIndex); + Register loadVariable(uint32 frameIndex); Register loadImmediate(double value); - void saveVariable(int32 frameIndex, Register value); + void saveVariable(uint32 frameIndex, Register value); Register loadName(StringAtom &name); Register getProperty(StringAtom &name, Register base); @@ -210,7 +224,7 @@ namespace JavaScript { void beginWhileStatement(uint32 pos); - void endWhileExpression(Register condition); + void endWhileExpression(Register condition, ICodeOp branchOp = BRANCH_NE); void endWhileStatement();