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)
static_cast<Branch *>(*ii)->itsOperand1 = labels[static_cast<Branch *>(*ii)->itsOperand1]->itsOffset;
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;
}
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<WhileCodeState *>(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<BranchCond * >(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<Return * >(instr);
s << "R" << t->itsOperand1;
}
break;
}
s << "\n";
}
@ -612,6 +639,3 @@ namespace JavaScript {
} // namespace JavaScript

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

@ -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<StringAtom*, Register, Register> SetProp;
typedef Instruction_2<StringAtom*, Register> LoadName, SaveName;
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_2<int32, Register> BranchCond;
typedef Instruction_3<Register, Register, Register> Arithmetic;
typedef Instruction_2<Register, Register> Move;
typedef Instruction_1<Register> Return;
typedef std::vector<Instruction *> 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();

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

@ -51,17 +51,24 @@ namespace JavaScript {
if ((*ii)->itsOp == BRANCH)
static_cast<Branch *>(*ii)->itsOperand1 = labels[static_cast<Branch *>(*ii)->itsOperand1]->itsOffset;
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;
}
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<WhileCodeState *>(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<BranchCond * >(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<Return * >(instr);
s << "R" << t->itsOperand1;
}
break;
}
s << "\n";
}
@ -612,6 +639,3 @@ namespace JavaScript {
} // namespace JavaScript

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

@ -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<StringAtom*, Register, Register> SetProp;
typedef Instruction_2<StringAtom*, Register> LoadName, SaveName;
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_2<int32, Register> BranchCond;
typedef Instruction_3<Register, Register, Register> Arithmetic;
typedef Instruction_2<Register, Register> Move;
typedef Instruction_1<Register> Return;
typedef std::vector<Instruction *> 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();