Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerSH4.h (149402 => 149403)
--- trunk/Source/_javascript_Core/assembler/MacroAssemblerSH4.h 2013-04-30 22:05:50 UTC (rev 149402)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerSH4.h 2013-04-30 22:10:51 UTC (rev 149403)
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2013 Cisco Systems, Inc. All rights reserved.
* Copyright (C) 2009-2011 STMicroelectronics. All rights reserved.
* Copyright (C) 2008 Apple Inc. All rights reserved.
*
@@ -183,39 +184,28 @@
void lshift32(RegisterID shiftamount, RegisterID dest)
{
- if (shiftamount == SH4Registers::r0)
- m_assembler.andlImm8r(0x1f, shiftamount);
- else {
- RegisterID scr = claimScratch();
- m_assembler.loadConstant(0x1f, scr);
- m_assembler.andlRegReg(scr, shiftamount);
- releaseScratch(scr);
- }
- m_assembler.shllRegReg(dest, shiftamount);
+ RegisterID shiftTmp = claimScratch();
+ m_assembler.loadConstant(0x1f, shiftTmp);
+ m_assembler.andlRegReg(shiftamount, shiftTmp);
+ m_assembler.shldRegReg(dest, shiftTmp);
+ releaseScratch(shiftTmp);
}
- void rshift32(int imm, RegisterID dest)
- {
- RegisterID scr = claimScratch();
- m_assembler.loadConstant(-imm, scr);
- m_assembler.shaRegReg(dest, scr);
- releaseScratch(scr);
- }
-
void lshift32(TrustedImm32 imm, RegisterID dest)
{
- if (!imm.m_value)
+ int immMasked = imm.m_value & 0x1f;
+ if (!immMasked)
return;
- if ((imm.m_value == 1) || (imm.m_value == 2) || (imm.m_value == 8) || (imm.m_value == 16)) {
- m_assembler.shllImm8r(imm.m_value, dest);
+ if ((immMasked == 1) || (immMasked == 2) || (immMasked == 8) || (immMasked == 16)) {
+ m_assembler.shllImm8r(immMasked, dest);
return;
}
- RegisterID scr = claimScratch();
- m_assembler.loadConstant(imm.m_value & 0x1f, scr);
- m_assembler.shllRegReg(dest, scr);
- releaseScratch(scr);
+ RegisterID shiftTmp = claimScratch();
+ m_assembler.loadConstant(immMasked, shiftTmp);
+ m_assembler.shldRegReg(dest, shiftTmp);
+ releaseScratch(shiftTmp);
}
void lshift32(RegisterID src, TrustedImm32 shiftamount, RegisterID dest)
@@ -296,22 +286,29 @@
void rshift32(RegisterID shiftamount, RegisterID dest)
{
- if (shiftamount == SH4Registers::r0)
- m_assembler.andlImm8r(0x1f, shiftamount);
- else {
- RegisterID scr = claimScratch();
- m_assembler.loadConstant(0x1f, scr);
- m_assembler.andlRegReg(scr, shiftamount);
- releaseScratch(scr);
- }
- m_assembler.neg(shiftamount, shiftamount);
- m_assembler.shaRegReg(dest, shiftamount);
+ RegisterID shiftTmp = claimScratch();
+ m_assembler.loadConstant(0x1f, shiftTmp);
+ m_assembler.andlRegReg(shiftamount, shiftTmp);
+ m_assembler.neg(shiftTmp, shiftTmp);
+ m_assembler.shadRegReg(dest, shiftTmp);
+ releaseScratch(shiftTmp);
}
void rshift32(TrustedImm32 imm, RegisterID dest)
{
- if (imm.m_value & 0x1f)
- rshift32(imm.m_value & 0x1f, dest);
+ int immMasked = imm.m_value & 0x1f;
+ if (!immMasked)
+ return;
+
+ if (immMasked == 1) {
+ m_assembler.sharImm8r(immMasked, dest);
+ return;
+ }
+
+ RegisterID shiftTmp = claimScratch();
+ m_assembler.loadConstant(-immMasked, shiftTmp);
+ m_assembler.shadRegReg(dest, shiftTmp);
+ releaseScratch(shiftTmp);
}
void rshift32(RegisterID src, TrustedImm32 imm, RegisterID dest)
@@ -1938,7 +1935,7 @@
m_assembler.stsmacl(dest);
m_assembler.movImm8(-31, scr);
m_assembler.movlRegReg(dest, scr1);
- m_assembler.shaRegReg(scr1, scr);
+ m_assembler.shadRegReg(scr1, scr);
m_assembler.stsmach(scr);
m_assembler.cmplRegReg(scr, scr1, SH4Condition(Equal));
releaseScratch(scr1);
@@ -2062,24 +2059,29 @@
void urshift32(RegisterID shiftamount, RegisterID dest)
{
- if (shiftamount == SH4Registers::r0)
- m_assembler.andlImm8r(0x1f, shiftamount);
- else {
- RegisterID scr = claimScratch();
- m_assembler.loadConstant(0x1f, scr);
- m_assembler.andlRegReg(scr, shiftamount);
- releaseScratch(scr);
- }
- m_assembler.neg(shiftamount, shiftamount);
- m_assembler.shllRegReg(dest, shiftamount);
+ RegisterID shiftTmp = claimScratch();
+ m_assembler.loadConstant(0x1f, shiftTmp);
+ m_assembler.andlRegReg(shiftamount, shiftTmp);
+ m_assembler.neg(shiftTmp, shiftTmp);
+ m_assembler.shldRegReg(dest, shiftTmp);
+ releaseScratch(shiftTmp);
}
void urshift32(TrustedImm32 imm, RegisterID dest)
{
- RegisterID scr = claimScratch();
- m_assembler.loadConstant(-(imm.m_value & 0x1f), scr);
- m_assembler.shaRegReg(dest, scr);
- releaseScratch(scr);
+ int immMasked = imm.m_value & 0x1f;
+ if (!immMasked)
+ return;
+
+ if ((immMasked == 1) || (immMasked == 2) || (immMasked == 8) || (immMasked == 16)) {
+ m_assembler.shlrImm8r(immMasked, dest);
+ return;
+ }
+
+ RegisterID shiftTmp = claimScratch();
+ m_assembler.loadConstant(-immMasked, shiftTmp);
+ m_assembler.shldRegReg(dest, shiftTmp);
+ releaseScratch(shiftTmp);
}
void urshift32(RegisterID src, TrustedImm32 shiftamount, RegisterID dest)
@@ -2201,13 +2203,12 @@
static void replaceWithJump(CodeLocationLabel instructionStart, CodeLocationLabel destination)
{
- RELEASE_ASSERT_NOT_REACHED();
+ SH4Assembler::replaceWithJump(instructionStart.dataLocation(), destination.dataLocation());
}
static ptrdiff_t maxJumpReplacementSize()
{
- RELEASE_ASSERT_NOT_REACHED();
- return 0;
+ return SH4Assembler::maxJumpReplacementSize();
}
static bool canJumpReplacePatchableBranchPtrWithPatch() { return false; }
Modified: trunk/Source/_javascript_Core/offlineasm/sh4.rb (149402 => 149403)
--- trunk/Source/_javascript_Core/offlineasm/sh4.rb 2013-04-30 22:05:50 UTC (rev 149402)
+++ trunk/Source/_javascript_Core/offlineasm/sh4.rb 2013-04-30 22:10:51 UTC (rev 149403)
@@ -153,7 +153,7 @@
# becomes:
#
# negi foo, tmp
-# shld tmp, bar
+# shad tmp, bar
#
def sh4LowerShiftOps(list)
@@ -163,35 +163,36 @@
if node.is_a? Instruction
case node.opcode
when "ulshifti", "ulshiftp", "urshifti", "urshiftp", "lshifti", "lshiftp", "rshifti", "rshiftp"
- if node.opcode[0,1] == "u"
+ if node.opcode[0, 1] == "u"
type = "l"
- direction = node.opcode[1,1]
+ direction = node.opcode[1, 1]
else
type = "a"
- direction = node.opcode[0,1]
+ direction = node.opcode[0, 1]
end
if node.operands[0].is_a? Immediate
- if node.operands[0].value == 0
+ maskedImm = Immediate.new(node.operands[0].codeOrigin, node.operands[0].value & 31)
+ if maskedImm.value == 0
# There is nothing to do here.
- elsif node.operands[0].value == 1 or (type == "l" and [2, 8, 16].include? node.operands[0].value)
- newList << Instruction.new(node.codeOrigin, "sh#{type}#{direction}x", node.operands)
+ elsif maskedImm.value == 1 or (type == "l" and [2, 8, 16].include? maskedImm.value)
+ newList << Instruction.new(node.codeOrigin, "sh#{type}#{direction}x", [maskedImm, node.operands[1]])
else
tmp = Tmp.new(node.codeOrigin, :gpr)
if direction == "l"
- newList << Instruction.new(node.codeOrigin, "move", [node.operands[0], tmp])
+ newList << Instruction.new(node.codeOrigin, "move", [maskedImm, tmp])
else
- newList << Instruction.new(node.codeOrigin, "move", [Immediate.new(node.operands[0].codeOrigin, -1 * node.operands[0].value), tmp])
+ newList << Instruction.new(node.codeOrigin, "move", [Immediate.new(node.operands[0].codeOrigin, -1 * maskedImm.value), tmp])
end
newList << Instruction.new(node.codeOrigin, "sh#{type}d", [tmp, node.operands[1]])
end
else
- if direction == "l"
- newList << Instruction.new(node.codeOrigin, "sh#{type}d", node.operands)
- else
- tmp = Tmp.new(node.codeOrigin, :gpr)
- newList << Instruction.new(node.codeOrigin, "negi", [node.operands[0], tmp])
- newList << Instruction.new(node.codeOrigin, "sh#{type}d", [tmp, node.operands[1]])
+ tmp = Tmp.new(node.codeOrigin, :gpr)
+ newList << Instruction.new(node.codeOrigin, "move", [Immediate.new(node.operands[0].codeOrigin, 31), tmp])
+ newList << Instruction.new(node.codeOrigin, "andi", [node.operands[0], tmp])
+ if direction == "r"
+ newList << Instruction.new(node.codeOrigin, "negi", [tmp, tmp])
end
+ newList << Instruction.new(node.codeOrigin, "sh#{type}d", [tmp, node.operands[1]])
end
else
newList << node
@@ -225,24 +226,39 @@
when /^b(addi|subi|ori|addp)/
op = $1
bc = $~.post_match
- branch = "b" + bc
case op
when "addi", "addp"
op = "addi"
- when "subi"
+ when "subi", "subp"
op = "subi"
- when "ori"
+ when "ori", "orp"
op = "ori"
end
if bc == "s"
- tmp = Tmp.new(node.codeOrigin, :gpr)
- newList << Instruction.new(node.codeOrigin, op, [node.operands[0], node.operands[1], tmp])
- newList << Instruction.new(node.codeOrigin, "bs", [tmp, node.operands[2]])
+ raise "Invalid operands number (#{node.operands.size})" unless node.operands.size == 3
+ if node.operands[1].is_a? RegisterID or node.operands[1].is_a? SpecialRegister
+ newList << Instruction.new(node.codeOrigin, op, node.operands[0..1])
+ newList << Instruction.new(node.codeOrigin, "bs", node.operands[1..2])
+ else
+ tmpVal = Tmp.new(node.codeOrigin, :gpr)
+ tmpPtr = Tmp.new(node.codeOrigin, :gpr)
+ addr = Address.new(node.codeOrigin, tmpPtr, Immediate.new(node.codeOrigin, 0))
+ newList << Instruction.new(node.codeOrigin, "leap", [node.operands[1], tmpPtr])
+ newList << Instruction.new(node.codeOrigin, "loadi", [addr, tmpVal])
+ newList << Instruction.new(node.codeOrigin, op, [node.operands[0], tmpVal])
+ newList << Instruction.new(node.codeOrigin, "storei", [tmpVal, addr])
+ newList << Instruction.new(node.codeOrigin, "bs", [tmpVal, node.operands[2]])
+ end
else
newList << node
end
+ when "bmulio", "bmulpo"
+ raise "Invalid operands number (#{node.operands.size})" unless node.operands.size == 3
+ tmp1 = Tmp.new(node.codeOrigin, :gpr)
+ tmp2 = Tmp.new(node.codeOrigin, :gpr)
+ newList << Instruction.new(node.codeOrigin, node.opcode, [tmp1, tmp2].concat(node.operands))
else
newList << node
end
@@ -485,9 +501,14 @@
def emitSH4CompareSet(cmpOpcode, neg, operands)
emitSH4IntCompare(cmpOpcode, operands)
- $asm.puts "movt #{operands[2].sh4Operand}"
- if neg
- $asm.puts "dt #{operands[2].sh4Operand}"
+ if !neg
+ $asm.puts "movt #{operands[2].sh4Operand}"
+ else
+ outlabel = LocalLabel.unique("compareSet")
+ $asm.puts "mov #0, #{operands[2].sh4Operand}"
+ $asm.puts "bt #{LocalLabelReference.new(codeOrigin, outlabel).asmLabel}"
+ $asm.puts "mov #1, #{operands[2].sh4Operand}"
+ outlabel.lower("SH4")
end
end
@@ -518,7 +539,7 @@
def emitSH4DoubleCondBranch(cmpOpcode, neg, operands)
if cmpOpcode == "lt"
- if (!neg)
+ if !neg
outlabel = LocalLabel.unique("dcbout")
$asm.puts "fcmp/gt #{sh4Operands([operands[1], operands[0]])}"
$asm.puts "bt #{LocalLabelReference.new(codeOrigin, outlabel).asmLabel}"
@@ -554,7 +575,7 @@
else
$asm.puts "add #{sh4Operands(operands)}"
end
- when "subi"
+ when "subi", "subp"
raise "#{opcode} with #{operands.size} operands is not handled yet" unless operands.size == 2
if operands[0].is_a? Immediate
$asm.puts "add #{sh4Operands([Immediate.new(codeOrigin, -1 * operands[0].value), operands[1]])}"
@@ -564,22 +585,22 @@
when "muli", "mulp"
$asm.puts "mul.l #{sh4Operands(operands[0..1])}"
$asm.puts "sts macl, #{operands[-1].sh4Operand}"
- when "negi"
+ when "negi", "negp"
if operands.size == 2
$asm.puts "neg #{sh4Operands(operands)}"
else
$asm.puts "neg #{sh4Operands([operands[0], operands[0]])}"
end
- when "andi", "ori", "xori"
+ when "andi", "andp", "ori", "orp", "xori", "xorp"
raise "#{opcode} with #{operands.size} operands is not handled yet" unless operands.size == 2
sh4opcode = opcode[0..-2]
$asm.puts "#{sh4opcode} #{sh4Operands(operands)}"
when "shllx", "shlrx"
raise "Unhandled parameters for opcode #{opcode}" unless operands[0].is_a? Immediate
if operands[0].value == 1
- $asm.puts "shl#{opcode[3,1]} #{operands[1].sh4Operand}"
+ $asm.puts "shl#{opcode[3, 1]} #{operands[1].sh4Operand}"
else
- $asm.puts "shl#{opcode[3,1]}#{operands[0].value} #{operands[1].sh4Operand}"
+ $asm.puts "shl#{opcode[3, 1]}#{operands[0].value} #{operands[1].sh4Operand}"
end
when "shld", "shad"
$asm.puts "#{opcode} #{sh4Operands(operands)}"
@@ -613,6 +634,8 @@
$asm.puts "float fpul, #{SH4_TMP_FPRS[0].sh4Operand}"
$asm.puts "fcmp/eq #{sh4Operands([operands[0], SH4_TMP_FPRS[0]])}"
$asm.puts "bf #{operands[2].asmLabel}"
+ $asm.puts "tst #{sh4Operands([operands[1], operands[1]])}"
+ $asm.puts "bt #{operands[2].asmLabel}"
when "bdnan"
emitSH4BranchIfNaN(operands)
when "bdneq"
@@ -625,17 +648,21 @@
emitSH4DoubleCondBranch("gt", true, operands)
when "bdgt"
emitSH4DoubleCondBranch("gt", false, operands)
- when "baddio", "bsubio"
+ when "baddio", "baddpo", "bsubio", "bsubpo"
raise "#{opcode} with #{operands.size} operands is not handled yet" unless operands.size == 3
- $asm.puts "#{opcode[1,3]}v #{sh4Operands([operands[0], operands[1]])}"
+ $asm.puts "#{opcode[1, 3]}v #{sh4Operands([operands[0], operands[1]])}"
$asm.puts "bt #{operands[2].asmLabel}"
- when "bmulio"
- $asm.puts "dmuls.l #{sh4Operands([operands[0], operands[1]])}"
- $asm.puts "sts mach, #{operands[-2].sh4Operand}"
- $asm.puts "tst #{sh4Operands([operands[-2], operands[-2]])}"
- $asm.puts "sts macl, #{operands[-2].sh4Operand}"
- $asm.puts "bf #{operands[-1].asmLabel}"
- when "btiz", "btpz", "btinz", "btpnz", "btbz", "btbnz"
+ when "bmulio", "bmulpo"
+ raise "Invalid operands number (#{operands.size})" unless operands.size == 5
+ $asm.puts "dmuls.l #{sh4Operands([operands[2], operands[3]])}"
+ $asm.puts "sts macl, #{operands[3].sh4Operand}"
+ $asm.puts "sts mach, #{operands[0].sh4Operand}"
+ $asm.puts "cmp/pz #{operands[3].sh4Operand}"
+ $asm.puts "movt #{operands[1].sh4Operand}"
+ $asm.puts "dt #{operands[1].sh4Operand}"
+ $asm.puts "cmp/eq #{sh4Operands([operands[0], operands[1]])}"
+ $asm.puts "bf #{operands[4].asmLabel}"
+ when "btiz", "btpz", "btbz", "btinz", "btpnz", "btbnz"
if operands.size == 3
$asm.puts "tst #{sh4Operands([operands[0], operands[1]])}"
else
@@ -645,38 +672,30 @@
$asm.puts "tst #{sh4Operands([operands[0], operands[0]])}"
end
end
- emitSH4BranchIfT(operands[-1], (opcode[-2,2] == "nz"))
- when "cbeq"
+ emitSH4BranchIfT(operands[-1], (opcode[-2, 2] == "nz"))
+ when "cieq", "cpeq", "cbeq"
emitSH4CompareSet("eq", false, operands)
- when "cieq", "cpeq"
- emitSH4CompareSet("eq", false, operands)
- when "cineq", "cpneq"
+ when "cineq", "cpneq", "cbneq"
emitSH4CompareSet("eq", true, operands)
- when "cib"
+ when "cib", "cpb", "cbb"
emitSH4CompareSet("hs", true, operands)
- when "bbeq"
+ when "bieq", "bpeq", "bbeq"
emitSH4CondBranch("eq", false, operands)
- when "bbneq"
+ when "bineq", "bpneq", "bbneq"
emitSH4CondBranch("eq", true, operands)
- when "bbb"
+ when "bib", "bpb", "bbb"
emitSH4CondBranch("hs", true, operands)
- when "bieq", "bpeq"
- emitSH4CondBranch("eq", false, operands)
- when "bineq", "bpneq"
- emitSH4CondBranch("eq", true, operands)
- when "bia", "bpa"
+ when "bia", "bpa", "bba"
emitSH4CondBranch("hi", false, operands)
when "biaeq", "bpaeq"
emitSH4CondBranch("hs", false, operands)
- when "bib", "bpb"
- emitSH4CondBranch("hs", true, operands)
- when "bigteq", "bpgteq"
+ when "bigteq", "bpgteq", "bbgteq"
emitSH4CondBranch("ge", false, operands)
- when "bilt", "bplt"
+ when "bilt", "bplt", "bblt"
emitSH4CondBranch("ge", true, operands)
- when "bigt", "bpgt"
+ when "bigt", "bpgt", "bbgt"
emitSH4CondBranch("gt", false, operands)
- when "bilteq", "bplteq"
+ when "bilteq", "bplteq", "bblteq"
emitSH4CondBranch("gt", true, operands)
when "bs"
$asm.puts "cmp/pz #{operands[0].sh4Operand}"