diff options
Diffstat (limited to 'Source/JavaScriptCore/offlineasm')
-rw-r--r-- | Source/JavaScriptCore/offlineasm/armv7.rb | 2 | ||||
-rw-r--r-- | Source/JavaScriptCore/offlineasm/asm.rb | 6 | ||||
-rw-r--r-- | Source/JavaScriptCore/offlineasm/cloop.rb | 169 | ||||
-rw-r--r-- | Source/JavaScriptCore/offlineasm/instructions.rb | 52 | ||||
-rw-r--r-- | Source/JavaScriptCore/offlineasm/x86.rb | 159 |
5 files changed, 345 insertions, 43 deletions
diff --git a/Source/JavaScriptCore/offlineasm/armv7.rb b/Source/JavaScriptCore/offlineasm/armv7.rb index ab0496f71..078be8c0f 100644 --- a/Source/JavaScriptCore/offlineasm/armv7.rb +++ b/Source/JavaScriptCore/offlineasm/armv7.rb @@ -401,7 +401,7 @@ class Instruction $asm.puts "pop #{operands[0].armV7Operand}" when "push" $asm.puts "push #{operands[0].armV7Operand}" - when "move", "sxi2p", "zxi2p" + when "move" if operands[0].is_a? Immediate armV7MoveImmediate(operands[0].value, operands[1]) else diff --git a/Source/JavaScriptCore/offlineasm/asm.rb b/Source/JavaScriptCore/offlineasm/asm.rb index 4d44c5e91..bf2426399 100644 --- a/Source/JavaScriptCore/offlineasm/asm.rb +++ b/Source/JavaScriptCore/offlineasm/asm.rb @@ -182,7 +182,11 @@ class Assembler end def self.cLabelReference(labelName) - "#{labelName}" + if /\Allint_op_/.match(labelName) + "op_#{$~.post_match}" # strip opcodes of their llint_ prefix. + else + "#{labelName}" + end end def self.cLocalLabelReference(labelName) diff --git a/Source/JavaScriptCore/offlineasm/cloop.rb b/Source/JavaScriptCore/offlineasm/cloop.rb index b3e319c4d..cbe7e2ca1 100644 --- a/Source/JavaScriptCore/offlineasm/cloop.rb +++ b/Source/JavaScriptCore/offlineasm/cloop.rb @@ -37,6 +37,8 @@ def cloopMapType(type) when :uint; ".u" when :int32; ".i32" when :uint32; ".u32" + when :int64; ".i64" + when :uint64; ".u64" when :int8; ".i8" when :uint8; ".u8" when :int8Ptr; ".i8p" @@ -44,7 +46,7 @@ def cloopMapType(type) when :nativeFunc; ".nativeFunc" when :double; ".d" when :castToDouble; ".castToDouble" - when :castToVoidPtr; ".castToVoidPtr" + when :castToInt64; ".castToInt64" when :opcode; ".opcode" else; raise "Unsupported type" @@ -141,9 +143,11 @@ class Immediate case type when :int8; "int8_t(#{valueStr})" when :int32; "int32_t(#{valueStr})" + when :int64; "int64_t(#{valueStr})" when :int; "intptr_t(#{valueStr})" when :uint8; "uint8_t(#{valueStr})" when :uint32; "uint32_t(#{valueStr})" + when :uint64; "uint64_t(#{valueStr})" when :uint; "uintptr_t(#{valueStr})" else raise "Not implemented immediate of type: #{type}" @@ -159,9 +163,11 @@ class Address case type when :int8; int8MemRef when :int32; int32MemRef + when :int64; int64MemRef when :int; intMemRef when :uint8; uint8MemRef when :uint32; uint32MemRef + when :uint64; uint64MemRef when :uint; uintMemRef when :opcode; opcodeMemRef when :nativeFunc; nativeFuncMemRef @@ -190,6 +196,9 @@ class Address def int32MemRef "*CAST<int32_t*>(#{pointerExpr})" end + def int64MemRef + "*CAST<int64_t*>(#{pointerExpr})" + end def intMemRef "*CAST<intptr_t*>(#{pointerExpr})" end @@ -202,6 +211,9 @@ class Address def uint32MemRef "*CAST<uint32_t*>(#{pointerExpr})" end + def uint64MemRef + "*CAST<uint64_t*>(#{pointerExpr})" + end def uintMemRef "*CAST<uintptr_t*>(#{pointerExpr})" end @@ -224,9 +236,11 @@ class BaseIndex case type when :int8; int8MemRef when :int32; int32MemRef + when :int64; int64MemRef when :int; intMemRef when :uint8; uint8MemRef when :uint32; uint32MemRef + when :uint64; uint64MemRef when :uint; uintMemRef when :opcode; opcodeMemRef else @@ -235,10 +249,10 @@ class BaseIndex end def pointerExpr if base.is_a? RegisterID and base.name == "sp" - offsetValue = "(#{index.clValue(:int32)} << #{scaleShift}) + #{offset.clValue})" + offsetValue = "(#{index.clValue} << #{scaleShift}) + #{offset.clValue})" "(ASSERT(#{offsetValue} == offsetof(JITStackFrame, globalData)), &sp->globalData)" else - "#{base.clValue(:int8Ptr)} + (#{index.clValue(:int32)} << #{scaleShift}) + #{offset.clValue}" + "#{base.clValue(:int8Ptr)} + (#{index.clValue} << #{scaleShift}) + #{offset.clValue}" end end def int8MemRef @@ -250,6 +264,9 @@ class BaseIndex def int32MemRef "*CAST<int32_t*>(#{pointerExpr})" end + def int64MemRef + "*CAST<int64_t*>(#{pointerExpr})" + end def intMemRef "*CAST<intptr_t*>(#{pointerExpr})" end @@ -262,6 +279,9 @@ class BaseIndex def uint32MemRef "*CAST<uint32_t*>(#{pointerExpr})" end + def uint64MemRef + "*CAST<uint64_t*>(#{pointerExpr})" + end def uintMemRef "*CAST<uintptr_t*>(#{pointerExpr})" end @@ -333,22 +353,47 @@ end def cloopEmitOperation(operands, type, operator) + raise unless type == :int || type == :uint || type == :int32 || type == :uint32 || \ + type == :int64 || type == :uint64 || type == :double if operands.size == 3 $asm.putc "#{operands[2].clValue(type)} = #{operands[1].clValue(type)} #{operator} #{operands[0].clValue(type)};" + if operands[2].is_a? RegisterID and (type == :int32 or type == :uint32) + $asm.putc "#{operands[2].dump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port. + end else raise unless operands.size == 2 raise unless not operands[1].is_a? Immediate $asm.putc "#{operands[1].clValue(type)} = #{operands[1].clValue(type)} #{operator} #{operands[0].clValue(type)};" + if operands[1].is_a? RegisterID and (type == :int32 or type == :uint32) + $asm.putc "#{operands[1].dump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port. + end end end def cloopEmitShiftOperation(operands, type, operator) + raise unless type == :int || type == :uint || type == :int32 || type == :uint32 || type == :int64 || type == :uint64 if operands.size == 3 $asm.putc "#{operands[2].clValue(type)} = #{operands[1].clValue(type)} #{operator} (#{operands[0].clValue(:int)} & 0x1f);" + if operands[2].is_a? RegisterID and (type == :int32 or type == :uint32) + $asm.putc "#{operands[2].dump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port. + end else raise unless operands.size == 2 raise unless not operands[1].is_a? Immediate $asm.putc "#{operands[1].clValue(type)} = #{operands[1].clValue(type)} #{operator} (#{operands[0].clValue(:int)} & 0x1f);" + if operands[1].is_a? RegisterID and (type == :int32 or type == :uint32) + $asm.putc "#{operands[1].dump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port. + end + end +end + +def cloopEmitUnaryOperation(operands, type, operator) + raise unless type == :int || type == :uint || type == :int32 || type == :uint32 || type == :int64 || type == :uint64 + raise unless operands.size == 1 + raise unless not operands[0].is_a? Immediate + $asm.putc "#{operands[0].clValue(type)} = #{operator}#{operands[0].clValue(type)};" + if operands[0].is_a? RegisterID and (type == :int32 or type == :uint32) + $asm.putc "#{operands[0].dump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port. end end @@ -410,6 +455,7 @@ def cloopEmitOpAndBranch(operands, operator, type, conditionTest) case type when :int; tempType = "intptr_t" when :int32; tempType = "int32_t" + when :int64; tempType = "int64_t" else raise "Unimplemented type" end @@ -512,65 +558,91 @@ class Instruction case opcode when "addi" cloopEmitOperation(operands, :int32, "+") + when "addq" + cloopEmitOperation(operands, :int64, "+") when "addp" cloopEmitOperation(operands, :int, "+") when "andi" cloopEmitOperation(operands, :int32, "&") + when "andq" + cloopEmitOperation(operands, :int64, "&") when "andp" cloopEmitOperation(operands, :int, "&") when "ori" cloopEmitOperation(operands, :int32, "|") + when "orq" + cloopEmitOperation(operands, :int64, "|") when "orp" cloopEmitOperation(operands, :int, "|") when "xori" cloopEmitOperation(operands, :int32, "^") + when "xorq" + cloopEmitOperation(operands, :int64, "^") when "xorp" cloopEmitOperation(operands, :int, "^") when "lshifti" cloopEmitShiftOperation(operands, :int32, "<<") + when "lshiftq" + cloopEmitShiftOperation(operands, :int64, "<<") when "lshiftp" cloopEmitShiftOperation(operands, :int, "<<") when "rshifti" cloopEmitShiftOperation(operands, :int32, ">>") + when "rshiftq" + cloopEmitShiftOperation(operands, :int64, ">>") when "rshiftp" cloopEmitShiftOperation(operands, :int, ">>") when "urshifti" cloopEmitShiftOperation(operands, :uint32, ">>") + when "urshiftq" + cloopEmitShiftOperation(operands, :uint64, ">>") when "urshiftp" cloopEmitShiftOperation(operands, :uint, ">>") when "muli" cloopEmitOperation(operands, :int32, "*") + when "mulq" + cloopEmitOperation(operands, :int64, "*") when "mulp" cloopEmitOperation(operands, :int, "*") when "subi" cloopEmitOperation(operands, :int32, "-") + when "subq" + cloopEmitOperation(operands, :int64, "-") when "subp" cloopEmitOperation(operands, :int, "-") when "negi" - $asm.putc "#{operands[0].clValue(:int32)} = -#{operands[0].clValue(:int32)};" + cloopEmitUnaryOperation(operands, :int32, "-") + when "negq" + cloopEmitUnaryOperation(operands, :int64, "-") when "negp" - $asm.putc "#{operands[0].clValue(:int)} = -#{operands[0].clValue(:int)};" + cloopEmitUnaryOperation(operands, :int, "-") when "noti" - $asm.putc "#{operands[0].clValue(:int32)} = !#{operands[0].clValue(:int32)};" + cloopEmitUnaryOperation(operands, :int32, "!") when "loadi" - $asm.putc "#{operands[1].clValue(:int)} = #{operands[0].uint32MemRef};" + $asm.putc "#{operands[1].clValue(:uint)} = #{operands[0].uint32MemRef};" + # There's no need to call clearHighWord() here because the above will + # automatically take care of 0 extension. when "loadis" $asm.putc "#{operands[1].clValue(:int)} = #{operands[0].int32MemRef};" + when "loadq" + $asm.putc "#{operands[1].clValue(:int64)} = #{operands[0].int64MemRef};" when "loadp" $asm.putc "#{operands[1].clValue(:int)} = #{operands[0].intMemRef};" when "storei" $asm.putc "#{operands[1].int32MemRef} = #{operands[0].clValue(:int32)};" + when "storeq" + $asm.putc "#{operands[1].int64MemRef} = #{operands[0].clValue(:int64)};" when "storep" $asm.putc "#{operands[1].intMemRef} = #{operands[0].clValue(:int)};" when "loadb" @@ -631,6 +703,7 @@ class Instruction when "td2i" $asm.putc "#{operands[1].clValue(:int)} = #{operands[0].clValue(:double)};" + $asm.putc "#{operands[1].dump}.clearHighWord();" when "bcd2i" # operands: srcDbl dstInt slowPath $asm.putc "{" @@ -639,20 +712,23 @@ class Instruction $asm.putc " if (asInt32 != d || (!asInt32 && signbit(d))) // true for -0.0" $asm.putc " goto #{operands[2].cLabel};" $asm.putc " #{operands[1].clValue} = asInt32;" + $asm.putc " #{operands[1].dump}.clearHighWord();" $asm.putc "}" when "move" $asm.putc "#{operands[1].clValue(:int)} = #{operands[0].clValue(:int)};" - when "sxi2p" - $asm.putc "#{operands[1].clValue(:int)} = #{operands[0].clValue(:int32)};" - when "zxi2p" - $asm.putc "#{operands[1].clValue(:uint)} = #{operands[0].clValue(:uint32)};" + when "sxi2q" + $asm.putc "#{operands[1].clValue(:int64)} = #{operands[0].clValue(:int32)};" + when "zxi2q" + $asm.putc "#{operands[1].clValue(:uint64)} = #{operands[0].clValue(:uint32)};" when "nop" $asm.putc "// nop" when "bbeq" cloopEmitCompareAndBranch(operands, :int8, "==") when "bieq" cloopEmitCompareAndBranch(operands, :int32, "==") + when "bqeq" + cloopEmitCompareAndBranch(operands, :int64, "==") when "bpeq" cloopEmitCompareAndBranch(operands, :int, "==") @@ -660,6 +736,8 @@ class Instruction cloopEmitCompareAndBranch(operands, :int8, "!=") when "bineq" cloopEmitCompareAndBranch(operands, :int32, "!=") + when "bqneq" + cloopEmitCompareAndBranch(operands, :int64, "!=") when "bpneq" cloopEmitCompareAndBranch(operands, :int, "!=") @@ -667,6 +745,8 @@ class Instruction cloopEmitCompareAndBranch(operands, :uint8, ">") when "bia" cloopEmitCompareAndBranch(operands, :uint32, ">") + when "bqa" + cloopEmitCompareAndBranch(operands, :uint64, ">") when "bpa" cloopEmitCompareAndBranch(operands, :uint, ">") @@ -674,6 +754,8 @@ class Instruction cloopEmitCompareAndBranch(operands, :uint8, ">=") when "biaeq" cloopEmitCompareAndBranch(operands, :uint32, ">=") + when "bqaeq" + cloopEmitCompareAndBranch(operands, :uint64, ">=") when "bpaeq" cloopEmitCompareAndBranch(operands, :uint, ">=") @@ -681,6 +763,8 @@ class Instruction cloopEmitCompareAndBranch(operands, :uint8, "<") when "bib" cloopEmitCompareAndBranch(operands, :uint32, "<") + when "bqb" + cloopEmitCompareAndBranch(operands, :uint64, "<") when "bpb" cloopEmitCompareAndBranch(operands, :uint, "<") @@ -688,6 +772,8 @@ class Instruction cloopEmitCompareAndBranch(operands, :uint8, "<=") when "bibeq" cloopEmitCompareAndBranch(operands, :uint32, "<=") + when "bqbeq" + cloopEmitCompareAndBranch(operands, :uint64, "<=") when "bpbeq" cloopEmitCompareAndBranch(operands, :uint, "<=") @@ -695,6 +781,8 @@ class Instruction cloopEmitCompareAndBranch(operands, :int8, ">") when "bigt" cloopEmitCompareAndBranch(operands, :int32, ">") + when "bqgt" + cloopEmitCompareAndBranch(operands, :int64, ">") when "bpgt" cloopEmitCompareAndBranch(operands, :int, ">") @@ -702,6 +790,8 @@ class Instruction cloopEmitCompareAndBranch(operands, :int8, ">=") when "bigteq" cloopEmitCompareAndBranch(operands, :int32, ">=") + when "bqgteq" + cloopEmitCompareAndBranch(operands, :int64, ">=") when "bpgteq" cloopEmitCompareAndBranch(operands, :int, ">=") @@ -709,6 +799,8 @@ class Instruction cloopEmitCompareAndBranch(operands, :int8, "<") when "bilt" cloopEmitCompareAndBranch(operands, :int32, "<") + when "bqlt" + cloopEmitCompareAndBranch(operands, :int64, "<") when "bplt" cloopEmitCompareAndBranch(operands, :int, "<") @@ -716,6 +808,8 @@ class Instruction cloopEmitCompareAndBranch(operands, :int8, "<=") when "bilteq" cloopEmitCompareAndBranch(operands, :int32, "<=") + when "bqlteq" + cloopEmitCompareAndBranch(operands, :int64, "<=") when "bplteq" cloopEmitCompareAndBranch(operands, :int, "<=") @@ -723,6 +817,8 @@ class Instruction cloopEmitTestAndBranchIf(operands, :int8, "== 0", operands[-1].cLabel) when "btiz" cloopEmitTestAndBranchIf(operands, :int32, "== 0", operands[-1].cLabel) + when "btqz" + cloopEmitTestAndBranchIf(operands, :int64, "== 0", operands[-1].cLabel) when "btpz" cloopEmitTestAndBranchIf(operands, :int, "== 0", operands[-1].cLabel) @@ -730,6 +826,8 @@ class Instruction cloopEmitTestAndBranchIf(operands, :int8, "!= 0", operands[-1].cLabel) when "btinz" cloopEmitTestAndBranchIf(operands, :int32, "!= 0", operands[-1].cLabel) + when "btqnz" + cloopEmitTestAndBranchIf(operands, :int64, "!= 0", operands[-1].cLabel) when "btpnz" cloopEmitTestAndBranchIf(operands, :int, "!= 0", operands[-1].cLabel) @@ -737,6 +835,8 @@ class Instruction cloopEmitTestAndBranchIf(operands, :int8, "< 0", operands[-1].cLabel) when "btis" cloopEmitTestAndBranchIf(operands, :int32, "< 0", operands[-1].cLabel) + when "btqs" + cloopEmitTestAndBranchIf(operands, :int64, "< 0", operands[-1].cLabel) when "btps" cloopEmitTestAndBranchIf(operands, :int, "< 0", operands[-1].cLabel) @@ -770,6 +870,8 @@ class Instruction cloopEmitCompareAndSet(operands, :uint8, "==") when "cieq" cloopEmitCompareAndSet(operands, :uint32, "==") + when "cqeq" + cloopEmitCompareAndSet(operands, :uint64, "==") when "cpeq" cloopEmitCompareAndSet(operands, :uint, "==") @@ -777,6 +879,8 @@ class Instruction cloopEmitCompareAndSet(operands, :uint8, "!=") when "cineq" cloopEmitCompareAndSet(operands, :uint32, "!=") + when "cqneq" + cloopEmitCompareAndSet(operands, :uint64, "!=") when "cpneq" cloopEmitCompareAndSet(operands, :uint, "!=") @@ -784,6 +888,8 @@ class Instruction cloopEmitCompareAndSet(operands, :uint8, ">") when "cia" cloopEmitCompareAndSet(operands, :uint32, ">") + when "cqa" + cloopEmitCompareAndSet(operands, :uint64, ">") when "cpa" cloopEmitCompareAndSet(operands, :uint, ">") @@ -791,6 +897,8 @@ class Instruction cloopEmitCompareAndSet(operands, :uint8, ">=") when "ciaeq" cloopEmitCompareAndSet(operands, :uint32, ">=") + when "cqaeq" + cloopEmitCompareAndSet(operands, :uint64, ">=") when "cpaeq" cloopEmitCompareAndSet(operands, :uint, ">=") @@ -798,6 +906,8 @@ class Instruction cloopEmitCompareAndSet(operands, :uint8, "<") when "cib" cloopEmitCompareAndSet(operands, :uint32, "<") + when "cqb" + cloopEmitCompareAndSet(operands, :uint64, "<") when "cpb" cloopEmitCompareAndSet(operands, :uint, "<") @@ -805,6 +915,8 @@ class Instruction cloopEmitCompareAndSet(operands, :uint8, "<=") when "cibeq" cloopEmitCompareAndSet(operands, :uint32, "<=") + when "cqbeq" + cloopEmitCompareAndSet(operands, :uint64, "<=") when "cpbeq" cloopEmitCompareAndSet(operands, :uint, "<=") @@ -812,6 +924,8 @@ class Instruction cloopEmitCompareAndSet(operands, :int8, ">") when "cigt" cloopEmitCompareAndSet(operands, :int32, ">") + when "cqgt" + cloopEmitCompareAndSet(operands, :int64, ">") when "cpgt" cloopEmitCompareAndSet(operands, :int, ">") @@ -819,6 +933,8 @@ class Instruction cloopEmitCompareAndSet(operands, :int8, ">=") when "cigteq" cloopEmitCompareAndSet(operands, :int32, ">=") + when "cqgteq" + cloopEmitCompareAndSet(operands, :int64, ">=") when "cpgteq" cloopEmitCompareAndSet(operands, :int, ">=") @@ -826,6 +942,8 @@ class Instruction cloopEmitCompareAndSet(operands, :int8, "<") when "cilt" cloopEmitCompareAndSet(operands, :int32, "<") + when "cqlt" + cloopEmitCompareAndSet(operands, :int64, "<") when "cplt" cloopEmitCompareAndSet(operands, :int, "<") @@ -833,6 +951,8 @@ class Instruction cloopEmitCompareAndSet(operands, :int8, "<=") when "cilteq" cloopEmitCompareAndSet(operands, :int32, "<=") + when "cqlteq" + cloopEmitCompareAndSet(operands, :int64, "<=") when "cplteq" cloopEmitCompareAndSet(operands, :int, "<=") @@ -840,6 +960,8 @@ class Instruction cloopEmitTestSet(operands, :int8, "< 0") when "tis" cloopEmitTestSet(operands, :int32, "< 0") + when "tqs" + cloopEmitTestSet(operands, :int64, "< 0") when "tps" cloopEmitTestSet(operands, :int, "< 0") @@ -847,6 +969,8 @@ class Instruction cloopEmitTestSet(operands, :int8, "== 0") when "tiz" cloopEmitTestSet(operands, :int32, "== 0") + when "tqz" + cloopEmitTestSet(operands, :int64, "== 0") when "tpz" cloopEmitTestSet(operands, :int, "== 0") @@ -854,6 +978,8 @@ class Instruction cloopEmitTestSet(operands, :int8, "!= 0") when "tinz" cloopEmitTestSet(operands, :int32, "!= 0") + when "tqnz" + cloopEmitTestSet(operands, :int64, "!= 0") when "tpnz" cloopEmitTestSet(operands, :int, "!= 0") @@ -864,7 +990,9 @@ class Instruction $asm.putc "{" $asm.putc " int64_t temp = t0.i32; // sign extend the low 32bit" $asm.putc " t0.i32 = temp; // low word" + $asm.putc " t0.clearHighWord();" $asm.putc " t1.i32 = uint64_t(temp) >> 32; // high word" + $asm.putc " t1.clearHighWord();" $asm.putc "}" # 64-bit instruction: idivi op1 (based on X64) @@ -884,7 +1012,9 @@ class Instruction $asm.putc " int64_t dividend = (int64_t(t1.u32) << 32) | t0.u32;" $asm.putc " int64_t divisor = #{operands[0].clValue(:int)};" $asm.putc " t1.i32 = dividend % divisor; // remainder" + $asm.putc " t1.clearHighWord();" $asm.putc " t0.i32 = dividend / divisor; // quotient" + $asm.putc " t0.clearHighWord();" $asm.putc "}" # 32-bit instruction: fii2d int32LoOp int32HiOp dblOp (based on ARMv7) @@ -897,15 +1027,15 @@ class Instruction when "fd2ii" $asm.putc "Double2Ints(#{operands[0].clValue(:double)}, #{operands[1].clValue}, #{operands[2].clValue});" - # 64-bit instruction: fp2d int64Op dblOp (based on X64) + # 64-bit instruction: fq2d int64Op dblOp (based on X64) # Copy a bit-encoded double in a 64-bit int register to a double register. - when "fp2d" + when "fq2d" $asm.putc "#{operands[1].clValue(:double)} = #{operands[0].clValue(:castToDouble)};" - # 64-bit instruction: fd2p dblOp int64Op (based on X64 instruction set) + # 64-bit instruction: fd2q dblOp int64Op (based on X64 instruction set) # Copy a double as a bit-encoded double into a 64-bit int register. - when "fd2p" - $asm.putc "#{operands[1].clValue(:voidPtr)} = #{operands[0].clValue(:castToVoidPtr)};" + when "fd2q" + $asm.putc "#{operands[1].clValue(:int64)} = #{operands[0].clValue(:castToInt64)};" when "leai" operands[0].cloopEmitLea(operands[1], :int32) @@ -926,6 +1056,13 @@ class Instruction when "baddinz" cloopEmitOpAndBranch(operands, "+", :int32, "!= 0") + when "baddqs" + cloopEmitOpAndBranch(operands, "+", :int64, "< 0") + when "baddqz" + cloopEmitOpAndBranch(operands, "+", :int64, "== 0") + when "baddqnz" + cloopEmitOpAndBranch(operands, "+", :int64, "!= 0") + when "baddps" cloopEmitOpAndBranch(operands, "+", :int, "< 0") when "baddpz" diff --git a/Source/JavaScriptCore/offlineasm/instructions.rb b/Source/JavaScriptCore/offlineasm/instructions.rb index ddb1bb90f..e047b2a16 100644 --- a/Source/JavaScriptCore/offlineasm/instructions.rb +++ b/Source/JavaScriptCore/offlineasm/instructions.rb @@ -33,15 +33,19 @@ MACRO_INSTRUCTIONS = "andi", "lshifti", "lshiftp", + "lshiftq", "muli", "negi", "negp", + "negq", "noti", "ori", "rshifti", "urshifti", "rshiftp", "urshiftp", + "rshiftq", + "urshiftq", "subi", "xori", "loadi", @@ -63,8 +67,8 @@ MACRO_INSTRUCTIONS = "ci2d", "fii2d", # usage: fii2d <gpr with least significant bits>, <gpr with most significant bits>, <fpr> "fd2ii", # usage: fd2ii <fpr>, <gpr with least significant bits>, <gpr with most significant bits> - "fp2d", - "fd2p", + "fq2d", + "fd2q", "bdeq", "bdneq", "bdgt", @@ -84,8 +88,8 @@ MACRO_INSTRUCTIONS = "pop", "push", "move", - "sxi2p", - "zxi2p", + "sxi2q", + "zxi2q", "nop", "bieq", "bineq", @@ -199,6 +203,46 @@ MACRO_INSTRUCTIONS = "baddps", "baddpz", "baddpnz", + "tqs", + "tqz", + "tqnz", + "peekq", + "pokeq", + "bqeq", + "bqneq", + "bqa", + "bqaeq", + "bqb", + "bqbeq", + "bqgt", + "bqgteq", + "bqlt", + "bqlteq", + "addq", + "mulq", + "andq", + "orq", + "subq", + "xorq", + "loadq", + "cqeq", + "cqneq", + "cqa", + "cqaeq", + "cqb", + "cqbeq", + "cqgt", + "cqgteq", + "cqlt", + "cqlteq", + "storeq", + "btqs", + "btqz", + "btqnz", + "baddqo", + "baddqs", + "baddqz", + "baddqnz", "bo", "bs", "bz", diff --git a/Source/JavaScriptCore/offlineasm/x86.rb b/Source/JavaScriptCore/offlineasm/x86.rb index 033c200d7..67cbd14b0 100644 --- a/Source/JavaScriptCore/offlineasm/x86.rb +++ b/Source/JavaScriptCore/offlineasm/x86.rb @@ -45,12 +45,15 @@ class SpecialRegister < NoChildren "%" + @name + "d" when :ptr "%" + @name + when :quad + "%" + @name else raise end end def x86CallOperand(kind) - "*#{x86Operand(kind)}" + # Call operands are not allowed to be partial registers. + "*#{x86Operand(:quad)}" end end @@ -82,6 +85,8 @@ class RegisterID "%eax" when :ptr isX64 ? "%rax" : "%eax" + when :quad + isX64 ? "%rax" : raise else raise end @@ -95,6 +100,8 @@ class RegisterID "%edx" when :ptr isX64 ? "%rdx" : "%edx" + when :quad + isX64 ? "%rdx" : raise else raise end @@ -108,6 +115,8 @@ class RegisterID "%ecx" when :ptr isX64 ? "%rcx" : "%ecx" + when :quad + isX64 ? "%rcx" : raise else raise end @@ -121,6 +130,8 @@ class RegisterID "%ebx" when :ptr isX64 ? "%rbx" : "%ebx" + when :quad + isX64 ? "%rbx" : raise else raise end @@ -134,6 +145,8 @@ class RegisterID "%esi" when :ptr isX64 ? "%rsi" : "%esi" + when :quad + isX64 ? "%rsi" : raise else raise end @@ -146,6 +159,8 @@ class RegisterID "%r13d" when :ptr "%r13" + when :quad + "%r13" else raise end @@ -173,6 +188,8 @@ class RegisterID "%esp" when :ptr isX64 ? "%rsp" : "%esp" + when :quad + isX64 ? "%rsp" : raise else raise end @@ -187,6 +204,8 @@ class RegisterID "%edi" when :ptr "%rdi" + when :quad + "%rdi" end when "t6" raise "Cannot use #{name} in 32-bit X86 at #{codeOriginString}" unless isX64 @@ -197,6 +216,8 @@ class RegisterID "%r10d" when :ptr "%r10" + when :quad + "%r10" end when "csr1" raise "Cannot use #{name} in 32-bit X86 at #{codeOriginString}" unless isX64 @@ -207,6 +228,8 @@ class RegisterID "%r14d" when :ptr "%r14" + when :quad + "%r14" end when "csr2" raise "Cannot use #{name} in 32-bit X86 at #{codeOriginString}" unless isX64 @@ -217,13 +240,15 @@ class RegisterID "%r15d" when :ptr "%r15" + when :quad + "%r15" end else raise "Bad register #{name} for X86 at #{codeOriginString}" end end def x86CallOperand(kind) - "*#{x86Operand(kind)}" + isX64 ? "*#{x86Operand(:quad)}" : "*#{x86Operand(:ptr)}" end end @@ -394,6 +419,8 @@ class Instruction "l" when :ptr isX64 ? "q" : "l" + when :quad + isX64 ? "q" : raise when :double "sd" else @@ -411,6 +438,8 @@ class Instruction 4 when :ptr isX64 ? 8 : 4 + when :quad + isX64 ? 8 : raise when :double 8 else @@ -607,9 +636,17 @@ class Instruction def handleMove if Immediate.new(nil, 0) == operands[0] and operands[1].is_a? RegisterID - $asm.puts "xor#{x86Suffix(:ptr)} #{operands[1].x86Operand(:ptr)}, #{operands[1].x86Operand(:ptr)}" + if isX64 + $asm.puts "xor#{x86Suffix(:quad)} #{operands[1].x86Operand(:quad)}, #{operands[1].x86Operand(:quad)}" + else + $asm.puts "xor#{x86Suffix(:ptr)} #{operands[1].x86Operand(:ptr)}, #{operands[1].x86Operand(:ptr)}" + end elsif operands[0] != operands[1] - $asm.puts "mov#{x86Suffix(:ptr)} #{x86Operands(:ptr, :ptr)}" + if isX64 + $asm.puts "mov#{x86Suffix(:quad)} #{x86Operands(:quad, :quad)}" + else + $asm.puts "mov#{x86Suffix(:ptr)} #{x86Operands(:ptr, :ptr)}" + end end end @@ -632,54 +669,76 @@ class Instruction handleX86Add(:int) when "addp" handleX86Add(:ptr) + when "addq" + handleX86Add(:quad) when "andi" handleX86Op("andl", :int) when "andp" handleX86Op("and#{x86Suffix(:ptr)}", :ptr) + when "andq" + handleX86Op("and#{x86Suffix(:quad)}", :quad) when "lshifti" handleX86Shift("sall", :int) when "lshiftp" handleX86Shift("sal#{x86Suffix(:ptr)}", :ptr) + when "lshiftq" + handleX86Shift("sal#{x86Suffix(:quad)}", :quad) when "muli" handleX86Mul(:int) when "mulp" handleX86Mul(:ptr) + when "mulq" + handleX86Mul(:quad) when "negi" $asm.puts "negl #{x86Operands(:int)}" when "negp" $asm.puts "neg#{x86Suffix(:ptr)} #{x86Operands(:ptr)}" + when "negq" + $asm.puts "neg#{x86Suffix(:quad)} #{x86Operands(:quad)}" when "noti" $asm.puts "notl #{x86Operands(:int)}" when "ori" handleX86Op("orl", :int) when "orp" handleX86Op("or#{x86Suffix(:ptr)}", :ptr) + when "orq" + handleX86Op("or#{x86Suffix(:quad)}", :quad) when "rshifti" handleX86Shift("sarl", :int) when "rshiftp" handleX86Shift("sar#{x86Suffix(:ptr)}", :ptr) + when "rshiftq" + handleX86Shift("sar#{x86Suffix(:quad)}", :quad) when "urshifti" handleX86Shift("shrl", :int) when "urshiftp" handleX86Shift("shr#{x86Suffix(:ptr)}", :ptr) + when "urshiftq" + handleX86Shift("shr#{x86Suffix(:quad)}", :quad) when "subi" handleX86Sub(:int) when "subp" handleX86Sub(:ptr) + when "subq" + handleX86Sub(:quad) when "xori" handleX86Op("xorl", :int) when "xorp" handleX86Op("xor#{x86Suffix(:ptr)}", :ptr) + when "xorq" + handleX86Op("xor#{x86Suffix(:quad)}", :quad) when "loadi", "storei" $asm.puts "movl #{x86Operands(:int, :int)}" when "loadis" if isX64 - $asm.puts "movslq #{x86Operands(:int, :ptr)}" + $asm.puts "movslq #{x86Operands(:int, :quad)}" else $asm.puts "movl #{x86Operands(:int, :int)}" end when "loadp", "storep" $asm.puts "mov#{x86Suffix(:ptr)} #{x86Operands(:ptr, :ptr)}" + when "loadq", "storeq" + $asm.puts "mov#{x86Suffix(:quad)} #{x86Operands(:quad, :quad)}" when "loadb" $asm.puts "movzbl #{operands[0].x86Operand(:byte)}, #{operands[1].x86Operand(:int)}" when "loadbs" @@ -761,60 +820,72 @@ class Instruction $asm.puts "push #{operands[0].x86Operand(:ptr)}" when "move" handleMove - when "sxi2p" - if isX64 - $asm.puts "movslq #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:ptr)}" - else - handleMove - end - when "zxi2p" - if isX64 - $asm.puts "movl #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:int)}" - else - handleMove - end + when "sxi2q" + $asm.puts "movslq #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:quad)}" + when "zxi2q" + $asm.puts "movl #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:int)}" when "nop" $asm.puts "nop" when "bieq" handleX86IntBranch("je", :int) when "bpeq" handleX86IntBranch("je", :ptr) + when "bqeq" + handleX86IntBranch("je", :quad) when "bineq" handleX86IntBranch("jne", :int) when "bpneq" handleX86IntBranch("jne", :ptr) + when "bqneq" + handleX86IntBranch("jne", :quad) when "bia" handleX86IntBranch("ja", :int) when "bpa" handleX86IntBranch("ja", :ptr) + when "bqa" + handleX86IntBranch("ja", :quad) when "biaeq" handleX86IntBranch("jae", :int) when "bpaeq" handleX86IntBranch("jae", :ptr) + when "bqaeq" + handleX86IntBranch("jae", :quad) when "bib" handleX86IntBranch("jb", :int) when "bpb" handleX86IntBranch("jb", :ptr) + when "bqb" + handleX86IntBranch("jb", :quad) when "bibeq" handleX86IntBranch("jbe", :int) when "bpbeq" handleX86IntBranch("jbe", :ptr) + when "bqbeq" + handleX86IntBranch("jbe", :quad) when "bigt" handleX86IntBranch("jg", :int) when "bpgt" handleX86IntBranch("jg", :ptr) + when "bqgt" + handleX86IntBranch("jg", :quad) when "bigteq" handleX86IntBranch("jge", :int) when "bpgteq" handleX86IntBranch("jge", :ptr) + when "bqgteq" + handleX86IntBranch("jge", :quad) when "bilt" handleX86IntBranch("jl", :int) when "bplt" handleX86IntBranch("jl", :ptr) + when "bqlt" + handleX86IntBranch("jl", :quad) when "bilteq" handleX86IntBranch("jle", :int) when "bplteq" handleX86IntBranch("jle", :ptr) + when "bqlteq" + handleX86IntBranch("jle", :quad) when "bbeq" handleX86IntBranch("je", :byte) when "bbneq" @@ -839,14 +910,20 @@ class Instruction handleX86BranchTest("js", :int) when "btps" handleX86BranchTest("js", :ptr) + when "btqs" + handleX86BranchTest("js", :quad) when "btiz" handleX86BranchTest("jz", :int) when "btpz" handleX86BranchTest("jz", :ptr) + when "btqz" + handleX86BranchTest("jz", :quad) when "btinz" handleX86BranchTest("jnz", :int) when "btpnz" handleX86BranchTest("jnz", :ptr) + when "btqnz" + handleX86BranchTest("jnz", :quad) when "btbs" handleX86BranchTest("js", :byte) when "btbz" @@ -859,18 +936,26 @@ class Instruction handleX86OpBranch("addl", "jo", :int) when "baddpo" handleX86OpBranch("add#{x86Suffix(:ptr)}", "jo", :ptr) + when "baddqo" + handleX86OpBranch("add#{x86Suffix(:quad)}", "jo", :quad) when "baddis" handleX86OpBranch("addl", "js", :int) when "baddps" handleX86OpBranch("add#{x86Suffix(:ptr)}", "js", :ptr) + when "baddqs" + handleX86OpBranch("add#{x86Suffix(:quad)}", "js", :quad) when "baddiz" handleX86OpBranch("addl", "jz", :int) when "baddpz" handleX86OpBranch("add#{x86Suffix(:ptr)}", "jz", :ptr) + when "baddqz" + handleX86OpBranch("add#{x86Suffix(:quad)}", "jz", :quad) when "baddinz" handleX86OpBranch("addl", "jnz", :int) when "baddpnz" handleX86OpBranch("add#{x86Suffix(:ptr)}", "jnz", :ptr) + when "baddqnz" + handleX86OpBranch("add#{x86Suffix(:quad)}", "jnz", :quad) when "bsubio" handleX86SubBranch("jo", :int) when "bsubis" @@ -907,60 +992,80 @@ class Instruction handleX86IntCompareSet("sete", :byte) when "cpeq" handleX86IntCompareSet("sete", :ptr) + when "cqeq" + handleX86IntCompareSet("sete", :quad) when "cineq" handleX86IntCompareSet("setne", :int) when "cbneq" handleX86IntCompareSet("setne", :byte) when "cpneq" handleX86IntCompareSet("setne", :ptr) + when "cqneq" + handleX86IntCompareSet("setne", :quad) when "cia" handleX86IntCompareSet("seta", :int) when "cba" handleX86IntCompareSet("seta", :byte) when "cpa" handleX86IntCompareSet("seta", :ptr) + when "cqa" + handleX86IntCompareSet("seta", :quad) when "ciaeq" handleX86IntCompareSet("setae", :int) when "cbaeq" handleX86IntCompareSet("setae", :byte) when "cpaeq" handleX86IntCompareSet("setae", :ptr) + when "cqaeq" + handleX86IntCompareSet("setae", :quad) when "cib" handleX86IntCompareSet("setb", :int) when "cbb" handleX86IntCompareSet("setb", :byte) when "cpb" handleX86IntCompareSet("setb", :ptr) + when "cqb" + handleX86IntCompareSet("setb", :quad) when "cibeq" handleX86IntCompareSet("setbe", :int) when "cbbeq" handleX86IntCompareSet("setbe", :byte) when "cpbeq" handleX86IntCompareSet("setbe", :ptr) + when "cqbeq" + handleX86IntCompareSet("setbe", :quad) when "cigt" handleX86IntCompareSet("setg", :int) when "cbgt" handleX86IntCompareSet("setg", :byte) when "cpgt" handleX86IntCompareSet("setg", :ptr) + when "cqgt" + handleX86IntCompareSet("setg", :quad) when "cigteq" handleX86IntCompareSet("setge", :int) when "cbgteq" handleX86IntCompareSet("setge", :byte) when "cpgteq" handleX86IntCompareSet("setge", :ptr) + when "cqgteq" + handleX86IntCompareSet("setge", :quad) when "cilt" handleX86IntCompareSet("setl", :int) when "cblt" handleX86IntCompareSet("setl", :byte) when "cplt" handleX86IntCompareSet("setl", :ptr) + when "cqlt" + handleX86IntCompareSet("setl", :quad) when "cilteq" handleX86IntCompareSet("setle", :int) when "cblteq" handleX86IntCompareSet("setle", :byte) when "cplteq" handleX86IntCompareSet("setle", :ptr) + when "cqlteq" + handleX86IntCompareSet("setle", :quad) when "tis" handleX86SetTest("sets", :int) when "tiz" @@ -973,6 +1078,12 @@ class Instruction handleX86SetTest("setz", :ptr) when "tpnz" handleX86SetTest("setnz", :ptr) + when "tqs" + handleX86SetTest("sets", :quad) + when "tqz" + handleX86SetTest("setz", :quad) + when "tqnz" + handleX86SetTest("setnz", :quad) when "tbs" handleX86SetTest("sets", :byte) when "tbz" @@ -982,9 +1093,15 @@ class Instruction when "peek" sp = RegisterID.new(nil, "sp") $asm.puts "mov#{x86Suffix(:ptr)} #{operands[0].value * x86Bytes(:ptr)}(#{sp.x86Operand(:ptr)}), #{operands[1].x86Operand(:ptr)}" + when "peekq" + sp = RegisterID.new(nil, "sp") + $asm.puts "mov#{x86Suffix(:quad)} #{operands[0].value * x86Bytes(:quad)}(#{sp.x86Operand(:ptr)}), #{operands[1].x86Operand(:quad)}" when "poke" sp = RegisterID.new(nil, "sp") $asm.puts "mov#{x86Suffix(:ptr)} #{operands[0].x86Operand(:ptr)}, #{operands[1].value * x86Bytes(:ptr)}(#{sp.x86Operand(:ptr)})" + when "pokeq" + sp = RegisterID.new(nil, "sp") + $asm.puts "mov#{x86Suffix(:quad)} #{operands[0].x86Operand(:quad)}, #{operands[1].value * x86Bytes(:quad)}(#{sp.x86Operand(:ptr)})" when "cdqi" $asm.puts "cdq" when "idivi" @@ -999,10 +1116,10 @@ class Instruction $asm.puts "movsd #{operands[0].x86Operand(:double)}, %xmm7" $asm.puts "psrlq $32, %xmm7" $asm.puts "movsd %xmm7, #{operands[2].x86Operand(:int)}" - when "fp2d" - $asm.puts "movd #{operands[0].x86Operand(:ptr)}, #{operands[1].x86Operand(:double)}" - when "fd2p" - $asm.puts "movd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:ptr)}" + when "fq2d" + $asm.puts "movd #{operands[0].x86Operand(:quad)}, #{operands[1].x86Operand(:double)}" + when "fd2q" + $asm.puts "movd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:quad)}" when "bo" $asm.puts "jo #{operands[0].asmLabel}" when "bs" |