Commit 4f745cab authored by Marius Wachtler's avatar Marius Wachtler

Use xor instead of a mov to clear a register

parent 051a4886
......@@ -300,6 +300,17 @@ void Assembler::movslq(Indirect src, Register dest) {
mov_generic(src, dest, MovType::SLQ);
}
void Assembler::clear_reg(Register reg) {
int reg_idx = reg.regnum;
// we don't need to generate a REX_W because 32bit instructions will clear the upper 32bits.
if (reg_idx >= 8) {
emitRex(REX_R | REX_B);
reg_idx -= 8;
}
emitByte(0x31);
emitModRM(0b11, reg_idx, reg_idx);
}
void Assembler::mov_generic(Indirect src, Register dest, MovType type) {
int rex;
switch (type) {
......
......@@ -144,6 +144,8 @@ public:
void movswq(Indirect scr, Register dest);
void movslq(Indirect scr, Register dest);
void clear_reg(Register reg); // = xor reg, reg
void mov_generic(Indirect src, Register dest, MovType type);
void push(Register reg);
......
......@@ -206,6 +206,11 @@ assembler::Register Rewriter::ConstLoader::findConst(uint64_t val, bool& found_v
void Rewriter::ConstLoader::loadConstIntoReg(uint64_t val, assembler::Register dst_reg) {
assert(rewriter->phase_emitting);
if (val == 0) {
rewriter->assembler->clear_reg(dst_reg);
return;
}
if (tryRegRegMove(val, dst_reg))
return;
......@@ -892,6 +897,9 @@ void Rewriter::_setupCall(bool has_side_effects, llvm::ArrayRef<RewriterVar*> ar
assembler::Immediate imm = var->tryGetAsImmediate(&is_immediate);
if (is_immediate) {
if (imm.val == 0)
assembler->clear_reg(r);
else
assembler->mov(imm, r);
addLocationToVar(var, l);
} else {
......
......@@ -810,7 +810,7 @@ void JitFragmentWriter::_emitOSRPoint(RewriterVar* result, RewriterVar* node_var
assembler->test(result_reg, result_reg);
{
assembler::ForwardJump je(*assembler, assembler::COND_EQUAL);
assembler->mov(assembler::Immediate(0ul), assembler::RAX); // TODO: use xor
assembler->clear_reg(assembler::RAX);
assembler->add(assembler::Immediate(JitCodeBlock::sp_adjustment), assembler::RSP);
assembler->pop(assembler::R12);
assembler->pop(assembler::R14);
......@@ -904,7 +904,7 @@ void JitFragmentWriter::_emitRecordType(RewriterVar* type_recorder_var, Rewriter
void JitFragmentWriter::_emitReturn(RewriterVar* return_val) {
return_val->getInReg(assembler::RDX, true);
assembler->mov(assembler::Immediate(0ul), assembler::RAX); // TODO: use xor
assembler->clear_reg(assembler::RAX);
assembler->add(assembler::Immediate(JitCodeBlock::sp_adjustment), assembler::RSP);
assembler->pop(assembler::R12);
assembler->pop(assembler::R14);
......
......@@ -117,7 +117,7 @@ class JitFragmentWriter;
// second_JitFragment:
// ...
// ; this shows how a AST_Return looks like
// mov $0,%rax ; rax contains the next block to interpret.
// xor %eax,%eax ; rax contains the next block to interpret.
// in this case 0 which means we are finished
// movabs $0x1270014108,%rdx ; rdx must contain the Box* value to return
// add $0x118,%rsp ; restore stack pointer
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment