summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/offlineasm
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
commit32761a6cee1d0dee366b885b7b9c777e67885688 (patch)
treed6bec92bebfb216f4126356e55518842c2f476a1 /Source/JavaScriptCore/offlineasm
parenta4e969f4965059196ca948db781e52f7cfebf19e (diff)
downloadWebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/JavaScriptCore/offlineasm')
-rw-r--r--Source/JavaScriptCore/offlineasm/arm.rb60
-rw-r--r--Source/JavaScriptCore/offlineasm/arm64.rb194
-rw-r--r--Source/JavaScriptCore/offlineasm/asm.rb130
-rw-r--r--Source/JavaScriptCore/offlineasm/ast.rb179
-rw-r--r--Source/JavaScriptCore/offlineasm/backends.rb48
-rw-r--r--Source/JavaScriptCore/offlineasm/cloop.rb72
-rw-r--r--Source/JavaScriptCore/offlineasm/config.rb7
-rw-r--r--Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb11
-rw-r--r--Source/JavaScriptCore/offlineasm/instructions.rb35
-rw-r--r--Source/JavaScriptCore/offlineasm/mips.rb243
-rw-r--r--Source/JavaScriptCore/offlineasm/parser.rb167
-rw-r--r--Source/JavaScriptCore/offlineasm/registers.rb26
-rw-r--r--Source/JavaScriptCore/offlineasm/self_hash.rb15
-rw-r--r--Source/JavaScriptCore/offlineasm/settings.rb59
-rw-r--r--Source/JavaScriptCore/offlineasm/sh4.rb137
-rw-r--r--Source/JavaScriptCore/offlineasm/transform.rb12
-rw-r--r--Source/JavaScriptCore/offlineasm/x86.rb785
17 files changed, 627 insertions, 1553 deletions
diff --git a/Source/JavaScriptCore/offlineasm/arm.rb b/Source/JavaScriptCore/offlineasm/arm.rb
index c8064a591..10b339eb6 100644
--- a/Source/JavaScriptCore/offlineasm/arm.rb
+++ b/Source/JavaScriptCore/offlineasm/arm.rb
@@ -1,4 +1,4 @@
-# Copyright (C) 2011, 2012, 2015-2016 Apple Inc. All rights reserved.
+# Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
# Copyright (C) 2013 University of Szeged. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -27,34 +27,6 @@ require "ast"
require "opt"
require "risc"
-# GPR conventions, to match the baseline JIT
-#
-# x0 => t0, a0, r0
-# x1 => t1, a1, r1
-# x2 => t2, a2, r2
-# x3 => t3, a3, r3
-# x6 => (callee-save scratch)
-# x7 => cfr (ARMv7 only)
-# x8 => t4 (callee-save)
-# x9 => t5 (callee-save)
-# x10 => (callee-save scratch)
-# x11 => cfr (ARM and ARMv7 traditional)
-# x12 => (callee-save scratch)
-# lr => lr
-# sp => sp
-# pc => pc
-#
-# FPR conventions, to match the baseline JIT
-#
-# d0 => ft0, fa0, fr
-# d1 => ft1, fa1
-# d2 => ft2
-# d3 => ft3
-# d4 => ft4
-# d5 => ft5
-# d6 => (scratch)
-# d7 => (scratch)
-
def isARMv7
case $activeBackend
when "ARMv7"
@@ -97,9 +69,7 @@ ARM_SCRATCH_FPR = SpecialRegister.new("d6")
def armMoveImmediate(value, register)
# Currently we only handle the simple cases, and fall back to mov/movt for the complex ones.
- if value.is_a? String
- $asm.puts "mov #{register.armOperand}, (#{value})"
- elsif value >= 0 && value < 256
+ if value >= 0 && value < 256
$asm.puts "mov #{register.armOperand}, \##{value}"
elsif (~value) >= 0 && (~value) < 256
$asm.puts "mvn #{register.armOperand}, \##{~value}"
@@ -136,8 +106,6 @@ class RegisterID
"lr"
when "sp"
"sp"
- when "pc"
- "pc"
else
raise "Bad register #{name} for ARM at #{codeOriginString}"
end
@@ -147,9 +115,9 @@ end
class FPRegisterID
def armOperand
case name
- when "ft0", "fr", "fa0"
+ when "ft0", "fr"
"d0"
- when "ft1", "fa1"
+ when "ft1"
"d1"
when "ft2"
"d2"
@@ -349,7 +317,6 @@ class Instruction
def lowerARMCommon
$asm.codeOrigin codeOriginString if $enableCodeOriginComments
$asm.annotation annotation if $enableInstrAnnotations
- $asm.debugAnnotation codeOrigin.debugDirective if $enableDebugAnnotations
case opcode
when "addi", "addp", "addis", "addps"
@@ -368,7 +335,7 @@ class Instruction
else
$asm.puts "adds #{operands[2].armOperand}, #{operands[1].armOperand}, #{operands[0].armOperand}"
end
- elsif operands.size == 3 and operands[0].register?
+ elsif operands.size == 3 and operands[0].immediate?
raise unless operands[1].register?
raise unless operands[2].register?
$asm.puts "adds #{armFlippedOperands(operands)}"
@@ -495,15 +462,24 @@ class Instruction
| op |
$asm.puts "push { #{op.armOperand} }"
}
+ when "popCalleeSaves"
+ if isARMv7
+ $asm.puts "pop {r4-r6, r8-r11}"
+ else
+ $asm.puts "pop {r4-r10}"
+ end
+ when "pushCalleeSaves"
+ if isARMv7
+ $asm.puts "push {r4-r6, r8-r11}"
+ else
+ $asm.puts "push {r4-r10}"
+ end
when "move"
if operands[0].immediate?
armMoveImmediate(operands[0].value, operands[1])
else
$asm.puts "mov #{armFlippedOperands(operands)}"
end
- when "mvlbl"
- $asm.puts "movw #{operands[1].armOperand}, \#:lower16:#{operands[0].value}"
- $asm.puts "movt #{operands[1].armOperand}, \#:upper16:#{operands[0].value}"
when "nop"
$asm.puts "nop"
when "bieq", "bpeq", "bbeq"
@@ -625,8 +601,6 @@ class Instruction
$asm.puts "smull #{operands[2].armOperand}, #{operands[3].armOperand}, #{operands[0].armOperand}, #{operands[1].armOperand}"
when "memfence"
$asm.puts "dmb sy"
- when "clrbp"
- $asm.puts "bic #{operands[2].armOperand}, #{operands[0].armOperand}, #{operands[1].armOperand}"
else
lowerDefault
end
diff --git a/Source/JavaScriptCore/offlineasm/arm64.rb b/Source/JavaScriptCore/offlineasm/arm64.rb
index ead489133..e0a23ff37 100644
--- a/Source/JavaScriptCore/offlineasm/arm64.rb
+++ b/Source/JavaScriptCore/offlineasm/arm64.rb
@@ -1,5 +1,4 @@
-# Copyright (C) 2011, 2012, 2014-2016 Apple Inc. All rights reserved.
-# Copyright (C) 2014 University of Szeged. All rights reserved.
+# Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -37,38 +36,32 @@ require "risc"
#
# GPR conventions, to match the baseline JIT:
#
-# x0 => t0, a0, r0
+# x0 => return value, cached result, first argument, t0, a0, r0
# x1 => t1, a1, r1
# x2 => t2, a2
-# x3 => t3, a3
-# x4 => t4
-# x5 => t5
-# x13 => (scratch)
-# x16 => (scratch)
-# x17 => (scratch)
-# x26 => csr0 (PB)
-# x27 => csr1 (tagTypeNumber)
-# x28 => csr2 (tagMask)
+# x3 => a3
+# x9 => (nonArgGPR1 in baseline)
+# x10 => t4 (unused in baseline)
+# x11 => t5 (unused in baseline)
+# x12 => t6 (unused in baseline)
+# x13 => scratch (unused in baseline)
+# x16 => scratch
+# x17 => scratch
+# x23 => t3
+# x27 => csr1 (tagTypeNumber)
+# x28 => csr2 (tagMask)
# x29 => cfr
# sp => sp
# lr => lr
#
-# FPR conventions, to match the baseline JIT:
+# FPR conentions, to match the baseline JIT:
#
-# q0 => ft0, fa0, fr
-# q1 => ft1, fa1
-# q2 => ft2, fa2
-# q3 => ft3, fa3
-# q4 => ft4 (unused in baseline)
-# q5 => ft5 (unused in baseline)
-# q8 => csfr0 (Only the lower 64 bits)
-# q9 => csfr1 (Only the lower 64 bits)
-# q10 => csfr2 (Only the lower 64 bits)
-# q11 => csfr3 (Only the lower 64 bits)
-# q12 => csfr4 (Only the lower 64 bits)
-# q13 => csfr5 (Only the lower 64 bits)
-# q14 => csfr6 (Only the lower 64 bits)
-# q15 => csfr7 (Only the lower 64 bits)
+# q0 => ft0
+# q1 => ft1
+# q2 => ft2
+# q3 => ft3
+# q4 => ft4 (unused in baseline)
+# q5 => ft5 (unused in baseline)
# q31 => scratch
def arm64GPRName(name, kind)
@@ -115,38 +108,26 @@ class RegisterID
arm64GPRName('x1', kind)
when 't2', 'a2'
arm64GPRName('x2', kind)
- when 't3', 'a3'
+ when 'a3'
arm64GPRName('x3', kind)
+ when 't3'
+ arm64GPRName('x23', kind)
when 't4'
- arm64GPRName('x4', kind)
+ arm64GPRName('x10', kind)
when 't5'
- arm64GPRName('x5', kind)
+ arm64GPRName('x11', kind)
+ when 't6'
+ arm64GPRName('x12', kind)
when 'cfr'
arm64GPRName('x29', kind)
- when 'csr0'
- arm64GPRName('x19', kind)
when 'csr1'
- arm64GPRName('x20', kind)
- when 'csr2'
- arm64GPRName('x21', kind)
- when 'csr3'
- arm64GPRName('x22', kind)
- when 'csr4'
- arm64GPRName('x23', kind)
- when 'csr5'
- arm64GPRName('x24', kind)
- when 'csr6'
- arm64GPRName('x25', kind)
- when 'csr7'
- arm64GPRName('x26', kind)
- when 'csr8'
arm64GPRName('x27', kind)
- when 'csr9'
+ when 'csr2'
arm64GPRName('x28', kind)
when 'sp'
'sp'
when 'lr'
- 'x30'
+ 'lr'
else
raise "Bad register name #{@name} at #{codeOriginString}"
end
@@ -156,34 +137,18 @@ end
class FPRegisterID
def arm64Operand(kind)
case @name
- when 'ft0', 'fr', 'fa0'
+ when 'ft0'
arm64FPRName('q0', kind)
- when 'ft1', 'fa1'
+ when 'ft1'
arm64FPRName('q1', kind)
- when 'ft2', 'fa2'
+ when 'ft2'
arm64FPRName('q2', kind)
- when 'ft3', 'fa3'
+ when 'ft3'
arm64FPRName('q3', kind)
when 'ft4'
arm64FPRName('q4', kind)
when 'ft5'
arm64FPRName('q5', kind)
- when 'csfr0'
- arm64FPRName('q8', kind)
- when 'csfr1'
- arm64FPRName('q9', kind)
- when 'csfr2'
- arm64FPRName('q10', kind)
- when 'csfr3'
- arm64FPRName('q11', kind)
- when 'csfr4'
- arm64FPRName('q12', kind)
- when 'csfr5'
- arm64FPRName('q13', kind)
- when 'csfr6'
- arm64FPRName('q14', kind)
- when 'csfr7'
- arm64FPRName('q15', kind)
else "Bad register name #{@name} at #{codeOriginString}"
end
end
@@ -230,64 +195,6 @@ end
# Actual lowering code follows.
#
-def arm64LowerMalformedLoadStoreAddresses(list)
- newList = []
-
- def isAddressMalformed(operand)
- operand.is_a? Address and not (-255..4095).include? operand.offset.value
- end
-
- list.each {
- | node |
- if node.is_a? Instruction
- if node.opcode =~ /^store/ and isAddressMalformed(node.operands[1])
- address = node.operands[1]
- tmp = Tmp.new(codeOrigin, :gpr)
- newList << Instruction.new(node.codeOrigin, "move", [address.offset, tmp])
- newList << Instruction.new(node.codeOrigin, node.opcode, [node.operands[0], BaseIndex.new(node.codeOrigin, address.base, tmp, 1, Immediate.new(codeOrigin, 0))], node.annotation)
- elsif node.opcode =~ /^load/ and isAddressMalformed(node.operands[0])
- address = node.operands[0]
- tmp = Tmp.new(codeOrigin, :gpr)
- newList << Instruction.new(node.codeOrigin, "move", [address.offset, tmp])
- newList << Instruction.new(node.codeOrigin, node.opcode, [BaseIndex.new(node.codeOrigin, address.base, tmp, 1, Immediate.new(codeOrigin, 0)), node.operands[1]], node.annotation)
- else
- newList << node
- end
- else
- newList << node
- end
- }
- newList
-end
-
-# Workaround for Cortex-A53 erratum (835769)
-def arm64CortexA53Fix835769(list)
- newList = []
- lastOpcodeUnsafe = false
-
- list.each {
- | node |
- if node.is_a? Instruction
- case node.opcode
- when /^store/, /^load/
- # List all macro instructions that can be lowered to a load, store or prefetch ARM64 assembly instruction
- lastOpcodeUnsafe = true
- when "muli", "mulp", "mulq", "smulli"
- # List all macro instructions that can be lowered to a 64-bit multiply-accumulate ARM64 assembly instruction
- # (defined as one of MADD, MSUB, SMADDL, SMSUBL, UMADDL or UMSUBL).
- if lastOpcodeUnsafe
- newList << Instruction.new(node.codeOrigin, "nopCortexA53Fix835769", [])
- end
- lastOpcodeUnsafe = false
- else
- lastOpcodeUnsafe = false
- end
- end
- newList << node
- }
- newList
-end
-
class Sequence
def getModifiedListARM64
result = @list
@@ -295,7 +202,6 @@ class Sequence
result = riscLowerSimpleBranchOps(result)
result = riscLowerHardBranchOps64(result)
result = riscLowerShiftOps(result)
- result = arm64LowerMalformedLoadStoreAddresses(result)
result = riscLowerMalformedAddresses(result) {
| node, address |
case node.opcode
@@ -344,7 +250,6 @@ class Sequence
result = riscLowerTest(result)
result = assignRegistersToTemporaries(result, :gpr, ARM64_EXTRA_GPRS)
result = assignRegistersToTemporaries(result, :fpr, ARM64_EXTRA_FPRS)
- result = arm64CortexA53Fix835769(result)
return result
end
end
@@ -462,7 +367,7 @@ def emitARM64MoveImmediate(value, target)
[48, 32, 16, 0].each {
| shift |
currentValue = (value >> shift) & 0xffff
- next if currentValue == (isNegative ? 0xffff : 0) and (shift != 0 or !first)
+ next if currentValue == (isNegative ? 0xffff : 0) and shift != 0
if first
if isNegative
$asm.puts "movn #{target.arm64Operand(:ptr)}, \##{(~currentValue) & 0xffff}, lsl \##{shift}"
@@ -480,7 +385,6 @@ class Instruction
def lowerARM64
$asm.comment codeOriginString
$asm.annotation annotation if $enableInstrAnnotations
- $asm.debugAnnotation codeOrigin.debugDirective if $enableDebugAnnotations
case opcode
when 'addi'
@@ -680,6 +584,22 @@ class Instruction
| ops |
$asm.puts "stp #{ops[0].arm64Operand(:ptr)}, #{ops[1].arm64Operand(:ptr)}, [sp, #-16]!"
}
+ when "popLRAndFP"
+ $asm.puts "ldp fp, lr, [sp], #16"
+ when "pushLRAndFP"
+ $asm.puts "stp fp, lr, [sp, #-16]!"
+ when "popCalleeSaves"
+ $asm.puts "ldp x28, x27, [sp], #16"
+ $asm.puts "ldp x26, x25, [sp], #16"
+ $asm.puts "ldp x24, x23, [sp], #16"
+ $asm.puts "ldp x22, x21, [sp], #16"
+ $asm.puts "ldp x20, x19, [sp], #16"
+ when "pushCalleeSaves"
+ $asm.puts "stp x20, x19, [sp, #-16]!"
+ $asm.puts "stp x22, x21, [sp, #-16]!"
+ $asm.puts "stp x24, x23, [sp, #-16]!"
+ $asm.puts "stp x26, x25, [sp, #-16]!"
+ $asm.puts "stp x28, x27, [sp, #-16]!"
when "move"
if operands[0].immediate?
emitARM64MoveImmediate(operands[0].value, operands[1])
@@ -687,13 +607,13 @@ class Instruction
emitARM64("mov", operands, :ptr)
end
when "sxi2p"
- emitARM64("sxtw", operands, [:int, :ptr])
+ emitARM64("sxtw", operands, :ptr)
when "sxi2q"
- emitARM64("sxtw", operands, [:int, :ptr])
+ emitARM64("sxtw", operands, :ptr)
when "zxi2p"
- emitARM64("uxtw", operands, [:int, :ptr])
+ emitARM64("uxtw", operands, :ptr)
when "zxi2q"
- emitARM64("uxtw", operands, [:int, :ptr])
+ emitARM64("uxtw", operands, :ptr)
when "nop"
$asm.puts "nop"
when "bieq", "bbeq"
@@ -898,12 +818,6 @@ class Instruction
$asm.puts "smaddl #{operands[2].arm64Operand(:ptr)}, #{operands[0].arm64Operand(:int)}, #{operands[1].arm64Operand(:int)}, xzr"
when "memfence"
$asm.puts "dmb sy"
- when "pcrtoaddr"
- $asm.puts "adr #{operands[1].arm64Operand(:ptr)}, #{operands[0].value}"
- when "nopCortexA53Fix835769"
- $asm.putStr("#if CPU(ARM64_CORTEXA53)")
- $asm.puts "nop"
- $asm.putStr("#endif")
else
lowerDefault
end
diff --git a/Source/JavaScriptCore/offlineasm/asm.rb b/Source/JavaScriptCore/offlineasm/asm.rb
index e93d85536..bf2426399 100644
--- a/Source/JavaScriptCore/offlineasm/asm.rb
+++ b/Source/JavaScriptCore/offlineasm/asm.rb
@@ -1,6 +1,6 @@
#!/usr/bin/env ruby
-# Copyright (C) 2011, 2016 Apple Inc. All rights reserved.
+# Copyright (C) 2011 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -47,32 +47,16 @@ class Assembler
@numGlobalLabels = 0
@newlineSpacerState = :none
- @lastlabel = ""
end
-
+
def enterAsm
- @outp.puts "OFFLINE_ASM_BEGIN" if !$emitWinAsm
-
- if !$emitWinAsm
- @outp.puts "OFFLINE_ASM_GLOBAL_LABEL(llintPCRangeStart)"
- else
- putsProc("llintPCRangeStart", "")
- putsProcEndIfNeeded
- end
+ @outp.puts "OFFLINE_ASM_BEGIN"
@state = :asm
- SourceFile.outputDotFileList(@outp) if $enableDebugAnnotations
end
def leaveAsm
- putsProcEndIfNeeded if $emitWinAsm
- if !$emitWinAsm
- @outp.puts "OFFLINE_ASM_GLOBAL_LABEL(llintPCRangeEnd)"
- else
- putsProc("llintPCRangeEnd", "")
- putsProcEndIfNeeded
- end
putsLastComment
- @outp.puts "OFFLINE_ASM_END" if !$emitWinAsm
+ @outp.puts "OFFLINE_ASM_END"
@state = :cpp
end
@@ -100,7 +84,7 @@ class Assembler
result += "#{@codeOrigin}"
end
if result != ""
- result = $commentPrefix + " " + result
+ result = "// " + result
end
# Reset all the components that we've just sent to be dumped.
@@ -153,11 +137,7 @@ class Assembler
def puts(*line)
raise unless @state == :asm
- if !$emitWinAsm
- @outp.puts(formatDump(" \"\\t" + line.join('') + "\\n\"", lastComment))
- else
- @outp.puts(formatDump(" " + line.join(''), lastComment))
- end
+ @outp.puts(formatDump(" \"\\t" + line.join('') + "\\n\"", lastComment))
end
def print(line)
@@ -172,45 +152,15 @@ class Assembler
end
end
- def putsProc(label, comment)
- raise unless $emitWinAsm
- @outp.puts(formatDump("#{label} PROC PUBLIC", comment))
- @lastlabel = label
- end
-
- def putsProcEndIfNeeded
- raise unless $emitWinAsm
- if @lastlabel != ""
- @outp.puts("#{@lastlabel} ENDP")
- end
- @lastlabel = ""
- end
-
- def putsLabel(labelName, isGlobal)
+ def putsLabel(labelName)
raise unless @state == :asm
@numGlobalLabels += 1
- putsProcEndIfNeeded if $emitWinAsm and isGlobal
putsNewlineSpacerIfAppropriate(:global)
@internalComment = $enableLabelCountComments ? "Global Label #{@numGlobalLabels}" : nil
- if isGlobal
- if !$emitWinAsm
- @outp.puts(formatDump("OFFLINE_ASM_GLOBAL_LABEL(#{labelName})", lastComment))
- else
- putsProc(labelName, lastComment)
- end
- elsif /\Allint_op_/.match(labelName)
- if !$emitWinAsm
- @outp.puts(formatDump("OFFLINE_ASM_OPCODE_LABEL(op_#{$~.post_match})", lastComment))
- else
- label = "llint_" + "op_#{$~.post_match}"
- @outp.puts(formatDump(" _#{label}:", lastComment))
- end
+ if /\Allint_op_/.match(labelName)
+ @outp.puts(formatDump("OFFLINE_ASM_OPCODE_LABEL(op_#{$~.post_match})", lastComment))
else
- if !$emitWinAsm
- @outp.puts(formatDump("OFFLINE_ASM_GLUE_LABEL(#{labelName})", lastComment))
- else
- @outp.puts(formatDump(" _#{labelName}:", lastComment))
- end
+ @outp.puts(formatDump("OFFLINE_ASM_GLUE_LABEL(#{labelName})", lastComment))
end
@newlineSpacerState = :none # After a global label, we can use another spacer.
end
@@ -220,35 +170,15 @@ class Assembler
@numLocalLabels += 1
@outp.puts("\n")
@internalComment = $enableLabelCountComments ? "Local Label #{@numLocalLabels}" : nil
- if !$emitWinAsm
- @outp.puts(formatDump(" OFFLINE_ASM_LOCAL_LABEL(#{labelName})", lastComment))
- else
- @outp.puts(formatDump(" #{labelName}:", lastComment))
- end
- end
-
- def self.externLabelReference(labelName)
- if !$emitWinAsm
- "\" LOCAL_REFERENCE(#{labelName}) \""
- else
- "#{labelName}"
- end
+ @outp.puts(formatDump(" OFFLINE_ASM_LOCAL_LABEL(#{labelName})", lastComment))
end
-
+
def self.labelReference(labelName)
- if !$emitWinAsm
- "\" LOCAL_LABEL_STRING(#{labelName}) \""
- else
- "_#{labelName}"
- end
+ "\" LOCAL_REFERENCE(#{labelName}) \""
end
def self.localLabelReference(labelName)
- if !$emitWinAsm
- "\" LOCAL_LABEL_STRING(#{labelName}) \""
- else
- "#{labelName}"
- end
+ "\" LOCAL_LABEL_STRING(#{labelName}) \""
end
def self.cLabelReference(labelName)
@@ -270,13 +200,13 @@ class Assembler
@commentState = :one
when :one
if $enableCodeOriginComments
- @outp.puts " " + $commentPrefix + " #{@codeOrigin}"
- @outp.puts " " + $commentPrefix + " #{text}"
+ @outp.puts " // #{@codeOrigin}"
+ @outp.puts " // #{text}"
end
@codeOrigin = nil
@commentState = :many
when :many
- @outp.puts $commentPrefix + " #{text}" if $enableCodeOriginComments
+ @outp.puts "// #{text}" if $enableCodeOriginComments
else
raise
end
@@ -285,22 +215,17 @@ class Assembler
def comment(text)
@comment = text
end
-
def annotation(text)
@annotation = text
end
-
- def debugAnnotation(text)
- @outp.puts text
- end
end
-IncludeFile.processIncludeOptions()
-
asmFile = ARGV.shift
offsetsFile = ARGV.shift
outputFlnm = ARGV.shift
+$stderr.puts "offlineasm: Parsing #{asmFile} and #{offsetsFile} and creating assembly file #{outputFlnm}."
+
begin
configurationList = offsetsAndConfigurationIndex(offsetsFile)
rescue MissingMagicValuesException
@@ -308,16 +233,8 @@ rescue MissingMagicValuesException
exit 0
end
-# The MS compiler doesn't accept DWARF2 debug annotations.
-if isMSVC
- $enableDebugAnnotations = false
-end
-
-$emitWinAsm = isMSVC ? outputFlnm.index(".asm") != nil : false
-$commentPrefix = $emitWinAsm ? ";" : "//"
-
inputHash =
- $commentPrefix + " offlineasm input hash: " + parseHash(asmFile) +
+ "// offlineasm input hash: " + parseHash(asmFile) +
" " + Digest::SHA1.hexdigest(configurationList.map{|v| (v[0] + [v[1]]).join(' ')}.join(' ')) +
" " + selfHash
@@ -336,11 +253,11 @@ File.open(outputFlnm, "w") {
| outp |
$output = outp
$output.puts inputHash
-
+
$asm = Assembler.new($output)
ast = parse(asmFile)
-
+
configurationList.each {
| configuration |
offsetsList = configuration[0]
@@ -357,3 +274,6 @@ File.open(outputFlnm, "w") {
}
}
}
+
+$stderr.puts "offlineasm: Assembly file #{outputFlnm} successfully generated."
+
diff --git a/Source/JavaScriptCore/offlineasm/ast.rb b/Source/JavaScriptCore/offlineasm/ast.rb
index 1241b7fe5..74bccff56 100644
--- a/Source/JavaScriptCore/offlineasm/ast.rb
+++ b/Source/JavaScriptCore/offlineasm/ast.rb
@@ -229,10 +229,6 @@ class Immediate < NoChildren
true
end
- def immediateOperand?
- true
- end
-
def register?
false
end
@@ -259,10 +255,6 @@ class AddImmediates < Node
"(#{left.dump} + #{right.dump})"
end
- def value
- "#{left.value} + #{right.value}"
- end
-
def address?
false
end
@@ -275,10 +267,6 @@ class AddImmediates < Node
true
end
- def immediateOperand?
- true
- end
-
def register?
false
end
@@ -305,10 +293,6 @@ class SubImmediates < Node
"(#{left.dump} - #{right.dump})"
end
- def value
- "#{left.value} - #{right.value}"
- end
-
def address?
false
end
@@ -321,10 +305,6 @@ class SubImmediates < Node
true
end
- def immediateOperand?
- true
- end
-
def register?
false
end
@@ -363,10 +343,6 @@ class MulImmediates < Node
true
end
- def immediateOperand?
- false
- end
-
def register?
false
end
@@ -404,10 +380,6 @@ class NegImmediate < Node
true
end
- def immediateOperand?
- false
- end
-
def register?
false
end
@@ -446,10 +418,6 @@ class OrImmediates < Node
true
end
- def immediateOperand?
- false
- end
-
def register?
false
end
@@ -488,10 +456,6 @@ class AndImmediates < Node
true
end
- def immediateOperand?
- false
- end
-
def register?
false
end
@@ -530,10 +494,6 @@ class XorImmediates < Node
true
end
- def immediateOperand?
- false
- end
-
def register?
false
end
@@ -571,48 +531,6 @@ class BitnotImmediate < Node
true
end
- def immediateOperand?
- false
- end
-
- def register?
- false
- end
-end
-
-class StringLiteral < NoChildren
- attr_reader :value
-
- def initialize(codeOrigin, value)
- super(codeOrigin)
- @value = value[1..-2]
- raise "Bad string literal #{value.inspect} at #{codeOriginString}" unless value.is_a? String
- end
-
- def dump
- "#{value}"
- end
-
- def ==(other)
- other.is_a? StringLiteral and other.value == @value
- end
-
- def address?
- false
- end
-
- def label?
- false
- end
-
- def immediate?
- false
- end
-
- def immediateOperand?
- false
- end
-
def register?
false
end
@@ -689,10 +607,6 @@ class FPRegisterID < NoChildren
false
end
- def immediateOperand?
- false
- end
-
def register?
true
end
@@ -715,10 +629,6 @@ class SpecialRegister < NoChildren
false
end
- def immediateOperand?
- false
- end
-
def register?
true
end
@@ -789,10 +699,6 @@ class Address < Node
false
end
- def immediateOperand?
- true
- end
-
def register?
false
end
@@ -853,10 +759,6 @@ class BaseIndex < Node
false
end
- def immediateOperand?
- false
- end
-
def register?
false
end
@@ -890,10 +792,6 @@ class AbsoluteAddress < NoChildren
false
end
- def immediateOperand?
- true
- end
-
def register?
false
end
@@ -927,8 +825,6 @@ class Instruction < Node
$asm.putLocalAnnotation
when "globalAnnotation"
$asm.putGlobalAnnotation
- when "emit"
- $asm.puts "#{operands[0].dump}"
else
raise "Unhandled opcode #{opcode} at #{codeOriginString}"
end
@@ -968,7 +864,6 @@ class ConstDecl < Node
end
$labelMapping = {}
-$referencedExternLabels = Array.new
class Label < NoChildren
attr_reader :name
@@ -976,61 +871,17 @@ class Label < NoChildren
def initialize(codeOrigin, name)
super(codeOrigin)
@name = name
- @extern = true
- @global = false
end
- def self.forName(codeOrigin, name, definedInFile = false)
+ def self.forName(codeOrigin, name)
if $labelMapping[name]
raise "Label name collision: #{name}" unless $labelMapping[name].is_a? Label
else
$labelMapping[name] = Label.new(codeOrigin, name)
end
- if definedInFile
- $labelMapping[name].clearExtern()
- end
$labelMapping[name]
end
-
- def self.setAsGlobal(codeOrigin, name)
- if $labelMapping[name]
- label = $labelMapping[name]
- raise "Label: #{name} declared global multiple times" unless not label.global?
- label.setGlobal()
- else
- newLabel = Label.new(codeOrigin, name)
- newLabel.setGlobal()
- $labelMapping[name] = newLabel
- end
- end
-
- def self.resetReferenced
- $referencedExternLabels = Array.new
- end
-
- def self.forReferencedExtern()
- $referencedExternLabels.each {
- | label |
- yield "#{label.name}"
- }
- end
-
- def clearExtern
- @extern = false
- end
-
- def extern?
- @extern
- end
-
- def setGlobal
- @global = true
- end
-
- def global?
- @global
- end
-
+
def dump
"#{name}:"
end
@@ -1098,24 +949,10 @@ class LabelReference < Node
label.name
end
- def extern?
- $labelMapping[name].is_a? Label and $labelMapping[name].extern?
- end
-
- def used
- if !$referencedExternLabels.include?(@label) and extern?
- $referencedExternLabels.push(@label)
- end
- end
-
def dump
label.name
end
- def value
- asmLabel()
- end
-
def address?
false
end
@@ -1127,10 +964,6 @@ class LabelReference < Node
def immediate?
false
end
-
- def immediateOperand?
- true
- end
end
class LocalLabelReference < NoChildren
@@ -1156,10 +989,6 @@ class LocalLabelReference < NoChildren
def dump
label.name
end
-
- def value
- asmLabel()
- end
def address?
false
@@ -1172,10 +1001,6 @@ class LocalLabelReference < NoChildren
def immediate?
false
end
-
- def immediateOperand?
- true
- end
end
class Sequence < Node
diff --git a/Source/JavaScriptCore/offlineasm/backends.rb b/Source/JavaScriptCore/offlineasm/backends.rb
index 274441997..bf01b59b5 100644
--- a/Source/JavaScriptCore/offlineasm/backends.rb
+++ b/Source/JavaScriptCore/offlineasm/backends.rb
@@ -1,4 +1,4 @@
-# Copyright (C) 2011, 2016 Apple Inc. All rights reserved.
+# Copyright (C) 2011 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -33,9 +33,7 @@ require "cloop"
BACKENDS =
[
"X86",
- "X86_WIN",
"X86_64",
- "X86_64_WIN",
"ARM",
"ARMv7",
"ARMv7_TRADITIONAL",
@@ -53,9 +51,7 @@ BACKENDS =
WORKING_BACKENDS =
[
"X86",
- "X86_WIN",
"X86_64",
- "X86_64_WIN",
"ARM",
"ARMv7",
"ARMv7_TRADITIONAL",
@@ -67,37 +63,6 @@ WORKING_BACKENDS =
BACKEND_PATTERN = Regexp.new('\\A(' + BACKENDS.join(')|(') + ')\\Z')
-$allBackends = {}
-$validBackends = {}
-BACKENDS.each {
- | backend |
- $validBackends[backend] = true
- $allBackends[backend] = true
-}
-
-def includeOnlyBackends(list)
- newValidBackends = {}
- list.each {
- | backend |
- if $validBackends[backend]
- newValidBackends[backend] = true
- end
- }
- $validBackends = newValidBackends
-end
-
-def isBackend?(backend)
- $allBackends[backend]
-end
-
-def isValidBackend?(backend)
- $validBackends[backend]
-end
-
-def validBackends
- $validBackends.keys
-end
-
class Node
def lower(name)
begin
@@ -114,8 +79,7 @@ end
class Label
def lower(name)
- $asm.debugAnnotation codeOrigin.debugDirective if $enableDebugAnnotations
- $asm.putsLabel(self.name[1..-1], @global)
+ $asm.putsLabel(self.name[1..-1])
end
end
@@ -127,13 +91,8 @@ end
class LabelReference
def asmLabel
- if extern?
- Assembler.externLabelReference(name[1..-1])
- else
- Assembler.labelReference(name[1..-1])
- end
+ Assembler.labelReference(name[1..-1])
end
-
def cLabel
Assembler.cLabelReference(name[1..-1])
end
@@ -143,7 +102,6 @@ class LocalLabelReference
def asmLabel
Assembler.localLabelReference("_offlineasm_"+name[1..-1])
end
-
def cLabel
Assembler.cLocalLabelReference("_offlineasm_"+name[1..-1])
end
diff --git a/Source/JavaScriptCore/offlineasm/cloop.rb b/Source/JavaScriptCore/offlineasm/cloop.rb
index 7e939480e..852e864e9 100644
--- a/Source/JavaScriptCore/offlineasm/cloop.rb
+++ b/Source/JavaScriptCore/offlineasm/cloop.rb
@@ -1,4 +1,4 @@
-# Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
+# Copyright (C) 2012 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -68,22 +68,34 @@ C_LOOP_SCRATCH_FPR = SpecialRegister.new("d6")
class RegisterID
def clDump
case name
- # The cloop is modelled on the ARM implementation. Hence, the a0-a3
- # registers are aliases for r0-r3 i.e. t0-t3 in our case.
- when "t0", "a0", "r0"
+ when "a0"
+ "a0"
+ when "a1"
+ "a1"
+ when "a2"
+ "a2"
+ when "a3"
+ "a3"
+ when "a4"
+ "a4"
+ when "a5"
+ "a5"
+ when "a6"
+ "a6"
+ when "a6"
+ "a6"
+ when "t0"
"t0"
- when "t1", "a1", "r1"
+ when "t1"
"t1"
- when "t2", "a2"
+ when "t2"
"t2"
- when "t3", "a3"
+ when "t3"
"t3"
when "t4"
- "pc"
- when "t5"
- "t5"
- when "csr0"
- "pcBase"
+ "rPC"
+ when "t6"
+ "rBasePC"
when "csr1"
"tagTypeNumber"
when "csr2"
@@ -91,7 +103,7 @@ class RegisterID
when "cfr"
"cfr"
when "lr"
- "lr"
+ "rRetVPC"
when "sp"
"sp"
else
@@ -543,18 +555,14 @@ end
# operands: callTarget, currentFrame, currentPC
def cloopEmitCallSlowPath(operands)
$asm.putc "{"
- $asm.putc " SlowPathReturnType result = #{operands[0].cLabel}(#{operands[1].clDump}, #{operands[2].clDump});"
- $asm.putc " decodeResult(result, t0.vp, t1.vp);"
+ $asm.putc " ExecState* exec = CAST<ExecState*>(#{operands[1].clValue(:voidPtr)});"
+ $asm.putc " Instruction* pc = CAST<Instruction*>(#{operands[2].clValue(:voidPtr)});"
+ $asm.putc " SlowPathReturnType result = #{operands[0].cLabel}(exec, pc);"
+ $asm.putc " decodeResult(result, t0.instruction, t1.vp);"
$asm.putc "}"
end
-def cloopEmitCallSlowPathVoid(operands)
- $asm.putc "#{operands[0].cLabel}(#{operands[1].clDump}, #{operands[2].clDump});"
-end
-
class Instruction
- @@didReturnFromJSLabelCounter = 0
-
def lowerC_LOOP
$asm.codeOrigin codeOriginString if $enableCodeOriginComments
$asm.annotation annotation if $enableInstrAnnotations && (opcode != "cloopDo")
@@ -868,8 +876,7 @@ class Instruction
when "break"
$asm.putc "CRASH(); // break instruction not implemented."
when "ret"
- $asm.putc "opcode = lr.opcode;"
- $asm.putc "DISPATCH_OPCODE();"
+ $asm.putc "goto doReturnHelper;"
when "cbeq"
cloopEmitCompareAndSet(operands, :uint8, "==")
@@ -1090,17 +1097,8 @@ class Instruction
cloopEmitOpAndBranch(operands, "|", :int32, "!= 0")
when "memfence"
-
- when "push"
- operands.each {
- | op |
- $asm.putc "PUSH(#{op.clDump});"
- }
- when "pop"
- operands.each {
- | op |
- $asm.putc "POP(#{op.clDump});"
- }
+ when "pushCalleeSaves"
+ when "popCalleeSaves"
# A convenience and compact call to crash because we don't want to use
@@ -1115,11 +1113,8 @@ class Instruction
# use of the call instruction. Instead, we just implement JS calls
# as an opcode dispatch.
when "cloopCallJSFunction"
- @@didReturnFromJSLabelCounter += 1
- $asm.putc "lr.opcode = getOpcode(llint_cloop_did_return_from_js_#{@@didReturnFromJSLabelCounter});"
$asm.putc "opcode = #{operands[0].clValue(:opcode)};"
$asm.putc "DISPATCH_OPCODE();"
- $asm.putsLabel("llint_cloop_did_return_from_js_#{@@didReturnFromJSLabelCounter}", false)
# We can't do generic function calls with an arbitrary set of args, but
# fortunately we don't have to here. All native function calls always
@@ -1140,9 +1135,6 @@ class Instruction
when "cloopCallSlowPath"
cloopEmitCallSlowPath(operands)
- when "cloopCallSlowPathVoid"
- cloopEmitCallSlowPathVoid(operands)
-
# For debugging only. This is used to insert instrumentation into the
# generated LLIntAssembly.h during llint development only. Do not use
# for production code.
diff --git a/Source/JavaScriptCore/offlineasm/config.rb b/Source/JavaScriptCore/offlineasm/config.rb
index 468c5cdda..4c86eeceb 100644
--- a/Source/JavaScriptCore/offlineasm/config.rb
+++ b/Source/JavaScriptCore/offlineasm/config.rb
@@ -1,4 +1,4 @@
-# Copyright (C) 2012, 2016 Apple Inc. All rights reserved.
+# Copyright (C) 2012 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -55,8 +55,3 @@ $enableCodeOriginComments = true
# ...
#
$enableInstrAnnotations = false
-
-# Turns on generation of DWARF2 debug annotions for file and line numbers.
-# Allows for source level debuging of the original .asm files in a debugger.
-#
-$enableDebugAnnotations = false
diff --git a/Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb b/Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb
index aafa93416..81c28632c 100644
--- a/Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb
+++ b/Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb
@@ -34,16 +34,10 @@ require "self_hash"
require "settings"
require "transform"
-IncludeFile.processIncludeOptions()
-
inputFlnm = ARGV.shift
outputFlnm = ARGV.shift
-validBackends = ARGV.shift
-if validBackends
- $stderr.puts "Only dealing with backends: #{validBackends}"
- includeOnlyBackends(validBackends.split(","))
-end
+$stderr.puts "offlineasm: Parsing #{inputFlnm} and creating offset extractor #{outputFlnm}."
def emitMagicNumber
OFFSET_MAGIC_NUMBERS.each {
@@ -147,3 +141,6 @@ File.open(outputFlnm, "w") {
}
outp.puts "};"
}
+
+$stderr.puts "offlineasm: offset extractor #{outputFlnm} successfully generated."
+
diff --git a/Source/JavaScriptCore/offlineasm/instructions.rb b/Source/JavaScriptCore/offlineasm/instructions.rb
index 244928746..5a3463fc9 100644
--- a/Source/JavaScriptCore/offlineasm/instructions.rb
+++ b/Source/JavaScriptCore/offlineasm/instructions.rb
@@ -22,7 +22,6 @@
# THE POSSIBILITY OF SUCH DAMAGE.
require "config"
-require "set"
# Interesting invariant, which we take advantage of: branching instructions
# always begin with "b", and no non-branching instructions begin with "b".
@@ -30,7 +29,6 @@ require "set"
MACRO_INSTRUCTIONS =
[
- "emit",
"addi",
"andi",
"lshifti",
@@ -249,6 +247,8 @@ MACRO_INSTRUCTIONS =
"bnz",
"leai",
"leap",
+ "pushCalleeSaves",
+ "popCalleeSaves",
"memfence"
]
@@ -258,16 +258,10 @@ X86_INSTRUCTIONS =
"idivi"
]
-ARM_INSTRUCTIONS =
- [
- "clrbp",
- "mvlbl"
- ]
-
ARM64_INSTRUCTIONS =
[
- "pcrtoaddr", # Address from PC relative offset - adr instruction
- "nopFixCortexA53Err835769" # nop on Cortex-A53 (nothing otherwise)
+ "popLRAndFP", # ARM64 requires registers to be pushed and popped in pairs,
+ "pushLRAndFP" # therefore we do LR (link register) and FP (frame pointer) together.
]
RISC_INSTRUCTIONS =
@@ -281,20 +275,16 @@ RISC_INSTRUCTIONS =
MIPS_INSTRUCTIONS =
[
- "la",
"movz",
"movn",
- "setcallreg",
"slt",
"sltu",
- "pichdr"
+ "pichdr",
+ "pichdrra"
]
SH4_INSTRUCTIONS =
[
- "flushcp",
- "alignformova",
- "mova",
"shllx",
"shlrx",
"shld",
@@ -309,11 +299,10 @@ SH4_INSTRUCTIONS =
CXX_INSTRUCTIONS =
[
- "cloopCrash", # no operands
- "cloopCallJSFunction", # operands: callee
- "cloopCallNative", # operands: callee
- "cloopCallSlowPath", # operands: callTarget, currentFrame, currentPC
- "cloopCallSlowPathVoid", # operands: callTarget, currentFrame, currentPC
+ "cloopCrash", # no operands
+ "cloopCallJSFunction", # operands: callee
+ "cloopCallNative", # operands: callee
+ "cloopCallSlowPath", # operands: callTarget, currentFrame, currentPC
# For debugging only:
# Takes no operands but simply emits whatever follows in // comments as
@@ -324,9 +313,9 @@ CXX_INSTRUCTIONS =
"cloopDo", # no operands
]
-INSTRUCTIONS = MACRO_INSTRUCTIONS + X86_INSTRUCTIONS + ARM_INSTRUCTIONS + ARM64_INSTRUCTIONS + RISC_INSTRUCTIONS + MIPS_INSTRUCTIONS + SH4_INSTRUCTIONS + CXX_INSTRUCTIONS
+INSTRUCTIONS = MACRO_INSTRUCTIONS + X86_INSTRUCTIONS + ARM64_INSTRUCTIONS + RISC_INSTRUCTIONS + MIPS_INSTRUCTIONS + SH4_INSTRUCTIONS + CXX_INSTRUCTIONS
-INSTRUCTION_SET = INSTRUCTIONS.to_set
+INSTRUCTION_PATTERN = Regexp.new('\\A((' + INSTRUCTIONS.join(')|(') + '))\\Z')
def isBranch(instruction)
instruction =~ /^b/
diff --git a/Source/JavaScriptCore/offlineasm/mips.rb b/Source/JavaScriptCore/offlineasm/mips.rb
index 53bb9c143..686f58f16 100644
--- a/Source/JavaScriptCore/offlineasm/mips.rb
+++ b/Source/JavaScriptCore/offlineasm/mips.rb
@@ -24,43 +24,6 @@
require 'risc'
-# GPR conventions, to match the baseline JIT
-#
-# $a0 => a0
-# $a1 => a1
-# $a2 => a2
-# $a3 => a3
-# $v0 => t0, r0
-# $v1 => t1, r1
-# $t0 => (scratch)
-# $t1 => (scratch)
-# $t2 => t2
-# $t3 => t3
-# $t4 => t4
-# $t5 => t5
-# $t6 => t6
-# $t7 => (scratch)
-# $t8 => (scratch)
-# $t9 => (stores the callee of a call opcode)
-# $gp => (globals)
-# $s4 => (callee-save used to preserve $gp across calls)
-# $ra => lr
-# $sp => sp
-# $fp => cfr
-#
-# FPR conventions, to match the baseline JIT
-# We don't have fa2 or fa3!
-# $f0 => ft0, fr
-# $f2 => ft1
-# $f4 => ft2
-# $f6 => ft3
-# $f8 => ft4
-# $f10 => ft5
-# $f12 => fa0
-# $f14 => fa1
-# $f16 => (scratch)
-# $f18 => (scratch)
-
class Assembler
def putStr(str)
@outp.puts str
@@ -94,10 +57,12 @@ class SpecialRegister < NoChildren
end
end
-MIPS_TEMP_GPRS = [SpecialRegister.new("$t0"), SpecialRegister.new("$t1"), SpecialRegister.new("$t7"), SpecialRegister.new("$t8")]
+MIPS_TEMP_GPRS = [SpecialRegister.new("$t5"), SpecialRegister.new("$t6"), SpecialRegister.new("$t7"),
+ SpecialRegister.new("$t8")]
MIPS_ZERO_REG = SpecialRegister.new("$zero")
MIPS_GP_REG = SpecialRegister.new("$gp")
MIPS_GPSAVE_REG = SpecialRegister.new("$s4")
+MIPS_JUMP_REG = SpecialRegister.new("$ra")
MIPS_CALL_REG = SpecialRegister.new("$t9")
MIPS_TEMP_FPRS = [SpecialRegister.new("$f16")]
MIPS_SCRATCH_FPR = SpecialRegister.new("$f18")
@@ -121,18 +86,24 @@ class RegisterID
"$a2"
when "a3"
"$a3"
- when "t0", "r0"
+ when "r0", "t0"
"$v0"
- when "t1", "r1"
+ when "r1", "t1"
"$v1"
when "t2"
"$t2"
when "t3"
- "$t3"
- when "t4"
- "$t4"
+ "$s3"
+ when "t4" # PC reg in llint
+ "$s2"
when "t5"
"$t5"
+ when "t6"
+ "$t6"
+ when "t7"
+ "$t7"
+ when "t8"
+ "$t8"
when "cfr"
"$fp"
when "lr"
@@ -191,70 +162,6 @@ class AbsoluteAddress
end
#
-# Negate condition of branches to labels.
-#
-
-class Instruction
- def mipsNegateCondition(list)
- /^(b(add|sub|or|mul|t)?)([ipb])/.match(opcode)
- case $~.post_match
- when "eq"
- op = "neq"
- when "neq"
- op = "eq"
- when "z"
- op = "nz"
- when "nz"
- op = "z"
- when "gt"
- op = "lteq"
- when "gteq"
- op = "lt"
- when "lt"
- op = "gteq"
- when "lteq"
- op = "gt"
- when "a"
- op = "beq"
- when "b"
- op = "aeq"
- when "aeq"
- op = "b"
- when "beq"
- op = "a"
- else
- raise "Can't negate #{opcode} branch."
- end
- noBranch = LocalLabel.unique("nobranch")
- noBranchRef = LocalLabelReference.new(codeOrigin, noBranch)
- toRef = operands[-1]
- list << Instruction.new(codeOrigin, "#{$1}#{$3}#{op}", operands[0..-2].push(noBranchRef), annotation)
- list << Instruction.new(codeOrigin, "la", [toRef, MIPS_CALL_REG])
- list << Instruction.new(codeOrigin, "jmp", [MIPS_CALL_REG])
- list << noBranch
- end
-end
-
-def mipsLowerFarBranchOps(list)
- newList = []
- list.each {
- | node |
- if node.is_a? Instruction
- annotation = node.annotation
- case node.opcode
- when /^b(add|sub|or|mul|t)?([ipb])/
- if node.operands[-1].is_a? LabelReference
- node.mipsNegateCondition(newList)
- next
- end
- end
- end
- newList << node
- }
- newList
-end
-
-#
# Lower 'and' masked branches
#
@@ -265,10 +172,9 @@ def lowerMIPSCondBranch(list, condOp, node)
[node.operands[0], MIPS_ZERO_REG, node.operands[-1]],
node.annotation)
elsif node.operands.size == 3
- tl = condOp[-1, 1]
tmp = Tmp.new(node.codeOrigin, :gpr)
list << Instruction.new(node.codeOrigin,
- "and" + tl,
+ "andi",
[node.operands[0], node.operands[1], tmp],
node.annotation)
list << Instruction.new(node.codeOrigin,
@@ -525,8 +431,6 @@ def mipsLowerMisplacedImmediates(list)
end
when /^(addi|subi)/
newList << node.riscLowerMalformedImmediatesRecurse(newList, -0x7fff..0x7fff)
- when "andi", "andp", "ori", "orp", "xori", "xorp"
- newList << node.riscLowerMalformedImmediatesRecurse(newList, 0..0xffff)
else
newList << node
end
@@ -541,30 +445,6 @@ end
# Specialization of lowering of misplaced addresses.
#
-class LocalLabelReference
- def register?
- false
- end
-end
-
-def mipsAsRegister(preList, postList, operand, needRestore)
- tmp = MIPS_CALL_REG
- if operand.address?
- preList << Instruction.new(operand.codeOrigin, "loadp", [operand, MIPS_CALL_REG])
- elsif operand.is_a? LabelReference
- preList << Instruction.new(operand.codeOrigin, "la", [operand, MIPS_CALL_REG])
- elsif operand.register? and operand != MIPS_CALL_REG
- preList << Instruction.new(operand.codeOrigin, "move", [operand, MIPS_CALL_REG])
- else
- needRestore = false
- tmp = operand
- end
- if needRestore
- postList << Instruction.new(operand.codeOrigin, "move", [MIPS_GPSAVE_REG, MIPS_GP_REG])
- end
- tmp
-end
-
def mipsLowerMisplacedAddresses(list)
newList = []
list.each {
@@ -574,13 +454,33 @@ def mipsLowerMisplacedAddresses(list)
annotation = node.annotation
case node.opcode
when "jmp"
- newList << Instruction.new(node.codeOrigin,
- node.opcode,
- [mipsAsRegister(newList, [], node.operands[0], false)])
+ if node.operands[0].address?
+ newList << Instruction.new(node.operands[0].codeOrigin, "loadi", [node.operands[0], MIPS_JUMP_REG])
+ newList << Instruction.new(node.codeOrigin, node.opcode, [MIPS_JUMP_REG])
+ else
+ newList << Instruction.new(node.codeOrigin,
+ node.opcode,
+ [riscAsRegister(newList, postInstructions, node.operands[0], "p", false)])
+ end
when "call"
- newList << Instruction.new(node.codeOrigin,
- node.opcode,
- [mipsAsRegister(newList, postInstructions, node.operands[0], true)])
+ restoreGP = false;
+ tmp = MIPS_CALL_REG
+ if node.operands[0].address?
+ newList << Instruction.new(node.operands[0].codeOrigin, "loadp", [node.operands[0], MIPS_CALL_REG])
+ restoreGP = true;
+ elsif node.operands[0].is_a? LabelReference
+ tmp = node.operands[0]
+ restoreGP = true;
+ elsif node.operands[0].register?
+ newList << Instruction.new(node.operands[0].codeOrigin, "move", [node.operands[0], MIPS_CALL_REG])
+ restoreGP = true;
+ else
+ tmp = node.operands[0]
+ end
+ newList << Instruction.new(node.codeOrigin, node.opcode, [tmp])
+ if restoreGP
+ newList << Instruction.new(node.codeOrigin, "move", [MIPS_GPSAVE_REG, MIPS_GP_REG])
+ end
when "slt", "sltu"
newList << Instruction.new(node.codeOrigin,
node.opcode,
@@ -589,10 +489,6 @@ def mipsLowerMisplacedAddresses(list)
newList << Instruction.new(node.codeOrigin,
node.opcode,
riscAsRegisters(newList, [], node.operands, "b"))
- when "andb"
- newList << Instruction.new(node.codeOrigin,
- "andi",
- riscAsRegisters(newList, [], node.operands, "b"))
when /^(bz|bnz|bs|bo)/
tl = $~.post_match == "" ? "i" : $~.post_match
newList << Instruction.new(node.codeOrigin,
@@ -669,7 +565,7 @@ class Address
end
#
-# Add PIC compatible header code to all the LLInt rutins.
+# Add PIC compatible header code to prologue/entry rutins.
#
def mipsAddPICCode(list)
@@ -678,7 +574,13 @@ def mipsAddPICCode(list)
| node |
myList << node
if node.is_a? Label
- myList << Instruction.new(node.codeOrigin, "pichdr", [])
+ if /_prologue$/.match(node.name) || /^_llint_function_/.match(node.name)
+ # Functions called from trampoline/JIT codes.
+ myList << Instruction.new(node.codeOrigin, "pichdr", [])
+ elsif /_llint_op_catch/.match(node.name)
+ # Exception cactcher entry point function.
+ myList << Instruction.new(node.codeOrigin, "pichdrra", [])
+ end
end
}
myList
@@ -704,7 +606,6 @@ class Sequence
}
result = mipsAddPICCode(result)
- result = mipsLowerFarBranchOps(result)
result = mipsLowerSimpleBranchOps(result)
result = riscLowerSimpleBranchOps(result)
result = riscLowerHardBranchOps(result)
@@ -813,16 +714,6 @@ def emitMIPSDoubleBranch(branchOpcode, neg, operands)
end
end
-def emitMIPSJumpOrCall(opcode, operand)
- if operand.label?
- raise "Direct call/jump to a not local label." unless operand.is_a? LocalLabelReference
- $asm.puts "#{opcode} #{operand.asmLabel}"
- else
- raise "Invalid call/jump register." unless operand == MIPS_CALL_REG
- $asm.puts "#{opcode}r #{MIPS_CALL_REG.mipsOperand}"
- end
-end
-
class Instruction
def lowerMIPS
$asm.comment codeOriginString
@@ -893,8 +784,6 @@ class Instruction
$asm.puts "ldc1 #{mipsFlippedOperands(operands)}"
when "stored"
$asm.puts "sdc1 #{mipsOperands(operands)}"
- when "la"
- $asm.puts "la #{operands[1].mipsOperand}, #{operands[0].asmLabel}"
when "addd"
emitMIPS("add.d", operands)
when "divd"
@@ -961,6 +850,20 @@ class Instruction
$asm.puts "addiu $sp, $sp, -4"
$asm.puts "sw #{op.mipsOperand}, 0($sp)"
}
+ when "popCalleeSaves"
+ $asm.puts "lw $16, 0($sp)"
+ $asm.puts "lw $17, 4($sp)"
+ $asm.puts "lw $18, 8($sp)"
+ $asm.puts "lw $19, 12($sp)"
+ $asm.puts "lw $20, 16($sp)"
+ $asm.puts "addiu $sp, $sp, 20"
+ when "pushCalleeSaves"
+ $asm.puts "addiu $sp, $sp, -20"
+ $asm.puts "sw $20, 16($sp)"
+ $asm.puts "sw $19, 12($sp)"
+ $asm.puts "sw $18, 8($sp)"
+ $asm.puts "sw $17, 4($sp)"
+ $asm.puts "sw $16, 0($sp)"
when "move", "sxi2p", "zxi2p"
if operands[0].is_a? Immediate
mipsMoveImmediate(operands[0].value, operands[1])
@@ -982,9 +885,17 @@ class Instruction
when "bilteq", "bplteq", "bblteq"
$asm.puts "ble #{mipsOperands(operands[0..1])}, #{operands[2].asmLabel}"
when "jmp"
- emitMIPSJumpOrCall("j", operands[0])
+ if operands[0].label?
+ $asm.puts "j #{operands[0].asmLabel}"
+ else
+ $asm.puts "jr #{operands[0].mipsOperand}"
+ end
when "call"
- emitMIPSJumpOrCall("jal", operands[0])
+ if operands[0].label?
+ $asm.puts "jal #{operands[0].asmLabel}"
+ else
+ $asm.puts "jalr #{operands[0].mipsOperand}"
+ end
when "break"
$asm.puts "break"
when "ret"
@@ -1038,14 +949,16 @@ class Instruction
$asm.puts "movz #{operands[0].mipsOperand}, #{operands[1].mipsOperand}, #{operands[2].mipsOperand}"
when "movn"
$asm.puts "movn #{operands[0].mipsOperand}, #{operands[1].mipsOperand}, #{operands[2].mipsOperand}"
- when "setcallreg"
- $asm.puts "move #{MIPS_CALL_REG.mipsOperand}, #{operands[0].mipsOperand}"
when "slt", "sltb"
$asm.puts "slt #{operands[0].mipsOperand}, #{operands[1].mipsOperand}, #{operands[2].mipsOperand}"
when "sltu", "sltub"
$asm.puts "sltu #{operands[0].mipsOperand}, #{operands[1].mipsOperand}, #{operands[2].mipsOperand}"
when "pichdr"
- $asm.putStr("OFFLINE_ASM_CPLOAD(#{MIPS_CALL_REG.mipsOperand})")
+ $asm.putStr("OFFLINE_ASM_CPLOAD($25)")
+ $asm.puts "move $s4, $gp"
+ when "pichdrra"
+ $asm.putStr("OFFLINE_ASM_CPLOAD($31)")
+ $asm.puts "move $s4, $gp"
when "memfence"
$asm.puts "sync"
else
diff --git a/Source/JavaScriptCore/offlineasm/parser.rb b/Source/JavaScriptCore/offlineasm/parser.rb
index b44511245..3b9c67bed 100644
--- a/Source/JavaScriptCore/offlineasm/parser.rb
+++ b/Source/JavaScriptCore/offlineasm/parser.rb
@@ -1,4 +1,4 @@
-# Copyright (C) 2011, 2016 Apple Inc. All rights reserved.
+# Copyright (C) 2011 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -28,83 +28,19 @@ require "pathname"
require "registers"
require "self_hash"
-class SourceFile
- @@fileNames = []
-
- attr_reader :name, :fileNumber
-
- def SourceFile.outputDotFileList(outp)
- @@fileNames.each_index {
- | index |
- outp.puts "\".file #{index+1} \\\"#{@@fileNames[index]}\\\"\\n\""
- }
- end
-
- def initialize(fileName)
- @name = Pathname.new(fileName)
- pathName = "#{@name.realpath}"
- fileNumber = @@fileNames.index(pathName)
- if not fileNumber
- @@fileNames << pathName
- fileNumber = @@fileNames.length
- else
- fileNumber += 1 # File numbers are 1 based
- end
- @fileNumber = fileNumber
- end
-end
-
class CodeOrigin
- attr_reader :lineNumber
+ attr_reader :fileName, :lineNumber
- def initialize(sourceFile, lineNumber)
- @sourceFile = sourceFile
+ def initialize(fileName, lineNumber)
+ @fileName = fileName
@lineNumber = lineNumber
end
-
- def fileName
- @sourceFile.name
- end
-
- def debugDirective
- $emitWinAsm ? nil : "\".loc #{@sourceFile.fileNumber} #{lineNumber}\\n\""
- end
-
+
def to_s
"#{fileName}:#{lineNumber}"
end
end
-class IncludeFile
- @@includeDirs = []
-
- attr_reader :fileName
-
- def initialize(moduleName, defaultDir)
- directory = nil
- @@includeDirs.each {
- | includePath |
- fileName = includePath + (moduleName + ".asm")
- directory = includePath unless not File.file?(fileName)
- }
- if not directory
- directory = defaultDir
- end
-
- @fileName = directory + (moduleName + ".asm")
- end
-
- def self.processIncludeOptions()
- while ARGV[0][/^-I/]
- path = ARGV.shift[2..-1]
- if not path
- path = ARGV.shift
- end
- @@includeDirs << (path + "/")
- end
- end
-end
-
class Token
attr_reader :codeOrigin, :string
@@ -151,7 +87,8 @@ end
# The lexer. Takes a string and returns an array of tokens.
#
-def lex(str, file)
+def lex(str, fileName)
+ fileName = Pathname.new(fileName)
result = []
lineNumber = 1
annotation = nil
@@ -171,37 +108,35 @@ def lex(str, file)
# use of this for its cloopDo debugging utility even if
# enableInstrAnnotations is not enabled.
if annotation
- result << Annotation.new(CodeOrigin.new(file, lineNumber),
+ result << Annotation.new(CodeOrigin.new(fileName, lineNumber),
annotationType, annotation)
annotation = nil
end
- result << Token.new(CodeOrigin.new(file, lineNumber), $&)
+ result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
lineNumber += 1
when /\A[a-zA-Z]([a-zA-Z0-9_.]*)/
- result << Token.new(CodeOrigin.new(file, lineNumber), $&)
+ result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
when /\A\.([a-zA-Z0-9_]*)/
- result << Token.new(CodeOrigin.new(file, lineNumber), $&)
+ result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
when /\A_([a-zA-Z0-9_]*)/
- result << Token.new(CodeOrigin.new(file, lineNumber), $&)
+ result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
when /\A([ \t]+)/
# whitespace, ignore
whitespaceFound = true
str = $~.post_match
next
when /\A0x([0-9a-fA-F]+)/
- result << Token.new(CodeOrigin.new(file, lineNumber), $&.hex.to_s)
+ result << Token.new(CodeOrigin.new(fileName, lineNumber), $&.hex.to_s)
when /\A0([0-7]+)/
- result << Token.new(CodeOrigin.new(file, lineNumber), $&.oct.to_s)
+ result << Token.new(CodeOrigin.new(fileName, lineNumber), $&.oct.to_s)
when /\A([0-9]+)/
- result << Token.new(CodeOrigin.new(file, lineNumber), $&)
+ result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
when /\A::/
- result << Token.new(CodeOrigin.new(file, lineNumber), $&)
+ result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
when /\A[:,\(\)\[\]=\+\-~\|&^*]/
- result << Token.new(CodeOrigin.new(file, lineNumber), $&)
- when /\A".*"/
- result << Token.new(CodeOrigin.new(file, lineNumber), $&)
+ result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
else
- raise "Lexer error at #{CodeOrigin.new(file, lineNumber).to_s}, unexpected sequence #{str[0..20].inspect}"
+ raise "Lexer error at #{CodeOrigin.new(fileName, lineNumber).to_s}, unexpected sequence #{str[0..20].inspect}"
end
whitespaceFound = false
str = $~.post_match
@@ -218,13 +153,13 @@ def isRegister(token)
end
def isInstruction(token)
- INSTRUCTION_SET.member? token.string
+ token =~ INSTRUCTION_PATTERN
end
def isKeyword(token)
- token =~ /\A((true)|(false)|(if)|(then)|(else)|(elsif)|(end)|(and)|(or)|(not)|(global)|(macro)|(const)|(sizeof)|(error)|(include))\Z/ or
+ token =~ /\A((true)|(false)|(if)|(then)|(else)|(elsif)|(end)|(and)|(or)|(not)|(macro)|(const)|(sizeof)|(error)|(include))\Z/ or
token =~ REGISTER_PATTERN or
- isInstruction(token)
+ token =~ INSTRUCTION_PATTERN
end
def isIdentifier(token)
@@ -247,10 +182,6 @@ def isInteger(token)
token =~ /\A[0-9]/
end
-def isString(token)
- token =~ /\A".*"/
-end
-
#
# The parser. Takes an array of tokens and returns an AST. Methods
# other than parse(tokens) are not for public consumption.
@@ -436,10 +367,6 @@ class Parser
result = Immediate.new(@tokens[@idx].codeOrigin, @tokens[@idx].string.to_i)
@idx += 1
result
- elsif isString @tokens[@idx]
- result = StringLiteral.new(@tokens[@idx].codeOrigin, @tokens[@idx].string)
- @idx += 1
- result
elsif isIdentifier @tokens[@idx]
codeOrigin, names = parseColonColon
if names.size > 1
@@ -453,14 +380,6 @@ class Parser
@idx += 1
codeOrigin, names = parseColonColon
Sizeof.forName(codeOrigin, names.join('::'))
- elsif isLabel @tokens[@idx]
- result = LabelReference.new(@tokens[@idx].codeOrigin, Label.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string))
- @idx += 1
- result
- elsif isLocalLabel @tokens[@idx]
- result = LocalLabelReference.new(@tokens[@idx].codeOrigin, LocalLabel.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string))
- @idx += 1
- result
else
parseError
end
@@ -481,7 +400,7 @@ class Parser
end
def couldBeExpression
- @tokens[@idx] == "-" or @tokens[@idx] == "~" or @tokens[@idx] == "sizeof" or isInteger(@tokens[@idx]) or isString(@tokens[@idx]) or isVariable(@tokens[@idx]) or @tokens[@idx] == "("
+ @tokens[@idx] == "-" or @tokens[@idx] == "~" or @tokens[@idx] == "sizeof" or isInteger(@tokens[@idx]) or isVariable(@tokens[@idx]) or @tokens[@idx] == "("
end
def parseExpressionAdd
@@ -654,14 +573,6 @@ class Parser
body = parseSequence(/\Aend\Z/, "while inside of macro #{name}")
@idx += 1
list << Macro.new(codeOrigin, name, variables, body)
- elsif @tokens[@idx] == "global"
- codeOrigin = @tokens[@idx].codeOrigin
- @idx += 1
- skipNewLine
- parseError unless isLabel(@tokens[@idx])
- name = @tokens[@idx].string
- @idx += 1
- Label.setAsGlobal(codeOrigin, name)
elsif isInstruction @tokens[@idx]
codeOrigin = @tokens[@idx].codeOrigin
name = @tokens[@idx].string
@@ -766,7 +677,7 @@ class Parser
parseError unless @tokens[@idx] == ":"
# It's a label.
if isLabel name
- list << Label.forName(codeOrigin, name, true)
+ list << Label.forName(codeOrigin, name)
else
list << LocalLabel.forName(codeOrigin, name)
end
@@ -775,8 +686,9 @@ class Parser
@idx += 1
parseError unless isIdentifier(@tokens[@idx])
moduleName = @tokens[@idx].string
- fileName = IncludeFile.new(moduleName, @tokens[@idx].codeOrigin.fileName.dirname).fileName
+ fileName = @tokens[@idx].codeOrigin.fileName.dirname + (moduleName + ".asm")
@idx += 1
+ $stderr.puts "offlineasm: Including file #{fileName}"
list << parse(fileName)
else
parseError "Expecting terminal #{final} #{comment}"
@@ -784,33 +696,10 @@ class Parser
}
Sequence.new(firstCodeOrigin, list)
end
-
- def parseIncludes(final, comment)
- firstCodeOrigin = @tokens[@idx].codeOrigin
- fileList = []
- fileList << @tokens[@idx].codeOrigin.fileName
- loop {
- if (@idx == @tokens.length and not final) or (final and @tokens[@idx] =~ final)
- break
- elsif @tokens[@idx] == "include"
- @idx += 1
- parseError unless isIdentifier(@tokens[@idx])
- moduleName = @tokens[@idx].string
- fileName = IncludeFile.new(moduleName, @tokens[@idx].codeOrigin.fileName.dirname).fileName
- @idx += 1
-
- fileList << fileName
- else
- @idx += 1
- end
- }
-
- return fileList
- end
end
def parseData(data, fileName)
- parser = Parser.new(data, SourceFile.new(fileName))
+ parser = Parser.new(data, fileName)
parser.parseSequence(nil, "")
end
@@ -819,8 +708,6 @@ def parse(fileName)
end
def parseHash(fileName)
- parser = Parser.new(IO::read(fileName), SourceFile.new(fileName))
- fileList = parser.parseIncludes(nil, "")
- fileListHash(fileList)
+ dirHash(Pathname.new(fileName).dirname, /\.asm$/)
end
diff --git a/Source/JavaScriptCore/offlineasm/registers.rb b/Source/JavaScriptCore/offlineasm/registers.rb
index b6ed36d00..94e0767a6 100644
--- a/Source/JavaScriptCore/offlineasm/registers.rb
+++ b/Source/JavaScriptCore/offlineasm/registers.rb
@@ -31,6 +31,10 @@ GPRS =
"t3",
"t4",
"t5",
+ "t6",
+ "t7",
+ "t8",
+ "t9",
"cfr",
"a0",
"a1",
@@ -40,18 +44,10 @@ GPRS =
"r1",
"sp",
"lr",
- "pc",
+
# 64-bit only registers:
- "csr0",
- "csr1",
- "csr2",
- "csr3",
- "csr4",
- "csr5",
- "csr6",
- "csr7",
- "csr8",
- "csr9"
+ "csr1", # tag type number register
+ "csr2" # tag mask register
]
FPRS =
@@ -66,14 +62,6 @@ FPRS =
"fa1",
"fa2",
"fa3",
- "csfr0",
- "csfr1",
- "csfr2",
- "csfr3",
- "csfr4",
- "csfr5",
- "csfr6",
- "csfr7",
"fr"
]
diff --git a/Source/JavaScriptCore/offlineasm/self_hash.rb b/Source/JavaScriptCore/offlineasm/self_hash.rb
index 6c736ff5b..b91057391 100644
--- a/Source/JavaScriptCore/offlineasm/self_hash.rb
+++ b/Source/JavaScriptCore/offlineasm/self_hash.rb
@@ -45,21 +45,6 @@ def dirHash(directory, regexp)
end
#
-# fileListHash(fileList) -> SHA1 hexdigest
-#
-# Returns a hash of all files in the list.
-#
-
-def fileListHash(fileList)
- contents = ""
- fileList.each {
- | fileName |
- contents += IO::read(fileName)
- }
- return Digest::SHA1.hexdigest(contents)
-end
-
-#
# selfHash -> SHA1 hexdigest
#
# Returns a hash of the offlineasm source code. This allows dependency
diff --git a/Source/JavaScriptCore/offlineasm/settings.rb b/Source/JavaScriptCore/offlineasm/settings.rb
index eec092584..601934f99 100644
--- a/Source/JavaScriptCore/offlineasm/settings.rb
+++ b/Source/JavaScriptCore/offlineasm/settings.rb
@@ -54,28 +54,7 @@ def computeSettingsCombinations(ast)
settingsCombinator(settingsCombinations, newMap, remaining[1..-1])
end
- nonBackendSettings = ast.filter(Setting).uniq.collect{ |v| v.name }
- nonBackendSettings.delete_if {
- | setting |
- isBackend? setting
- }
-
- allBackendsFalse = {}
- BACKENDS.each {
- | backend |
- allBackendsFalse[backend] = false
- }
-
- # This will create entries for invalid backends. That's fine. It's necessary
- # because it ensures that generate_offsets_extractor (which knows about valid
- # backends) has settings indices that are compatible with what asm will see
- # (asm doesn't know about valid backends).
- BACKENDS.each {
- | backend |
- map = allBackendsFalse.clone
- map[backend] = true
- settingsCombinator(settingsCombinations, map, nonBackendSettings)
- }
+ settingsCombinator(settingsCombinations, {}, (ast.filter(Setting).uniq.collect{|v| v.name} + BACKENDS).uniq)
settingsCombinations
end
@@ -94,13 +73,15 @@ def forSettings(concreteSettings, ast)
selectedBackend = nil
BACKENDS.each {
| backend |
- if concreteSettings[backend]
- raise if selectedBackend
+ isSupported = concreteSettings[backend]
+ raise unless isSupported != nil
+ numClaimedBackends += if isSupported then 1 else 0 end
+ if isSupported
selectedBackend = backend
end
}
- return unless isValidBackend? selectedBackend
+ return if numClaimedBackends > 1
# Resolve the AST down to a low-level form (no macros or conditionals).
lowLevelAST = ast.resolveSettings(concreteSettings)
@@ -191,17 +172,7 @@ end
#
def emitCodeInConfiguration(concreteSettings, ast, backend)
- Label.resetReferenced
-
- if !$emitWinAsm
- $output.puts cppSettingsTest(concreteSettings)
- else
- if backend == "X86_WIN"
- $output.puts ".MODEL FLAT, C"
- end
- $output.puts "INCLUDE #{File.basename($output.path)}.sym"
- $output.puts "_TEXT SEGMENT"
- end
+ $output.puts cppSettingsTest(concreteSettings)
if isASTErroneous(ast)
$output.puts "#error \"Invalid configuration.\""
@@ -211,21 +182,7 @@ def emitCodeInConfiguration(concreteSettings, ast, backend)
yield concreteSettings, ast, backend
end
- if !$emitWinAsm
- $output.puts "#endif"
- else
- $output.puts "_TEXT ENDS"
- $output.puts "END"
-
- # Write symbols needed by MASM
- File.open("#{File.basename($output.path)}.sym", "w") {
- | outp |
- Label.forReferencedExtern {
- | name |
- outp.puts "EXTERN #{name[1..-1]} : near"
- }
- }
- end
+ $output.puts "#endif"
end
#
diff --git a/Source/JavaScriptCore/offlineasm/sh4.rb b/Source/JavaScriptCore/offlineasm/sh4.rb
index c847d564a..a804b29cc 100644
--- a/Source/JavaScriptCore/offlineasm/sh4.rb
+++ b/Source/JavaScriptCore/offlineasm/sh4.rb
@@ -24,33 +24,6 @@
require 'risc'
-# GPR conventions, to match the baseline JIT
-#
-# r0 => t0, r0
-# r1 => t1, r1
-# r2 => t4
-# r3 => t5
-# r4 => a0
-# r5 => a1
-# r6 => t2, a2
-# r7 => t3, a3
-# r10 => (scratch)
-# r11 => (scratch)
-# r13 => (scratch)
-# r14 => cfr
-# r15 => sp
-# pr => lr
-
-# FPR conventions, to match the baseline JIT
-# We don't have fa2 or fa3!
-# dr0 => ft0, fr
-# dr2 => ft1
-# dr4 => ft2, fa0
-# dr6 => ft3, fa1
-# dr8 => ft4
-# dr10 => ft5
-# dr12 => (scratch)
-
class Node
def sh4SingleHi
doubleOperand = sh4Operand
@@ -78,28 +51,32 @@ class SpecialRegister < NoChildren
end
end
-SH4_TMP_GPRS = [ SpecialRegister.new("r10"), SpecialRegister.new("r11"), SpecialRegister.new("r13") ]
-SH4_TMP_FPRS = [ SpecialRegister.new("dr12") ]
+SH4_TMP_GPRS = [ SpecialRegister.new("r3"), SpecialRegister.new("r11"), SpecialRegister.new("r13") ]
+SH4_TMP_FPRS = [ SpecialRegister.new("dr10") ]
class RegisterID
def sh4Operand
case name
- when "a0"
- "r4"
- when "a1"
- "r5"
- when "r0", "t0"
+ when "t0"
"r0"
- when "r1", "t1"
+ when "t1"
"r1"
- when "a2", "t2"
+ when "t2"
+ "r2"
+ when "t3"
+ "r10"
+ when "t4", "a0"
+ "r4"
+ when "t5", "a1"
+ "r5"
+ when "t6", "a2"
"r6"
- when "a3", "t3"
+ when "t7", "a3"
"r7"
- when "t4"
- "r2"
- when "t5"
- "r3"
+ when "t8"
+ "r8"
+ when "t9"
+ "r9"
when "cfr"
"r14"
when "sp"
@@ -119,14 +96,14 @@ class FPRegisterID
"dr0"
when "ft1"
"dr2"
- when "ft2", "fa0"
+ when "ft2"
"dr4"
- when "ft3", "fa1"
+ when "ft3"
"dr6"
when "ft4"
"dr8"
- when "ft5"
- "dr10"
+ when "fa0"
+ "dr12"
else
raise "Bad register #{name} for SH4 at #{codeOriginString}"
end
@@ -173,18 +150,6 @@ class AbsoluteAddress
end
end
-class LabelReference
- def sh4Operand
- value
- end
-end
-
-class SubImmediates < Node
- def sh4Operand
- "#{@left.sh4Operand} - #{@right.sh4Operand}"
- end
-end
-
class ConstPool < Node
attr_reader :size
attr_reader :entries
@@ -491,7 +456,7 @@ def sh4LowerMisplacedLabels(list)
newOperands = []
operands.each {
| operand |
- if operand.is_a? LabelReference and node.opcode != "mova"
+ if operand.is_a? LabelReference
tmp = Tmp.new(operand.codeOrigin, :gpr)
newList << Instruction.new(operand.codeOrigin, "move", [operand, tmp])
newOperands << tmp
@@ -584,13 +549,8 @@ def sh4LowerConstPool(list)
| node |
if node.is_a? Instruction
case node.opcode
- when "jmp", "ret", "flushcp"
- if node.opcode == "flushcp"
- outlabel = LocalLabel.unique("flushcp")
- newList << Instruction.new(codeOrigin, "jmp", [LocalLabelReference.new(codeOrigin, outlabel)])
- else
- newList << node
- end
+ when "jmp", "ret"
+ newList << node
if not currentPool16.empty?
newList << ConstPool.new(codeOrigin, currentPool16, 16)
currentPool16 = []
@@ -599,9 +559,6 @@ def sh4LowerConstPool(list)
newList << ConstPool.new(codeOrigin, currentPool32, 32)
currentPool32 = []
end
- if node.opcode == "flushcp"
- newList << outlabel
- end
when "move"
if node.operands[0].is_a? Immediate and not (-128..127).include? node.operands[0].value
poolEntry = nil
@@ -639,10 +596,6 @@ def sh4LowerConstPool(list)
currentPool32 << poolEntry
end
newList << Instruction.new(codeOrigin, "move", [poolEntry, node.operands[1]])
- elsif node.operands[0].is_a? SubImmediates
- poolEntry = ConstPoolEntry.new(codeOrigin, node.operands[0].sh4Operand, 32)
- currentPool32 << poolEntry
- newList << Instruction.new(codeOrigin, "move", [poolEntry, node.operands[1]])
else
newList << node
end
@@ -890,10 +843,7 @@ class Instruction
end
when "subi", "subp"
if operands.size == 3
- if operands[1].is_a? Immediate
- $asm.puts "mov #{sh4Operands([Immediate.new(codeOrigin, -1 * operands[1].value), operands[2]])}"
- $asm.puts "add #{sh4Operands([operands[0], operands[2]])}"
- elsif operands[1].sh4Operand == operands[2].sh4Operand
+ if operands[1].sh4Operand == operands[2].sh4Operand
$asm.puts "neg #{sh4Operands([operands[2], operands[2]])}"
$asm.puts "add #{sh4Operands([operands[0], operands[2]])}"
else
@@ -927,9 +877,6 @@ class Instruction
else
$asm.puts "shl#{opcode[3, 1]}#{operands[0].value} #{operands[1].sh4Operand}"
end
- when "shalx", "sharx"
- raise "Unhandled parameters for opcode #{opcode}" unless operands[0].is_a? Immediate and operands[0].value == 1
- $asm.puts "sha#{opcode[3, 1]} #{operands[1].sh4Operand}"
when "shld", "shad"
$asm.puts "#{opcode} #{sh4Operands(operands)}"
when "loaddReversedAndIncrementAddress"
@@ -1061,10 +1008,6 @@ class Instruction
$asm.puts "extu.w #{sh4Operands([operands[1], operands[1]])}"
when "loadi", "loadis", "loadp", "storei", "storep"
$asm.puts "mov.l #{sh4Operands(operands)}"
- when "alignformova"
- $asm.puts ".balign 4" # As balign directive is in a code section, fill value is 'nop' instruction.
- when "mova"
- $asm.puts "mova #{sh4Operands(operands)}"
when "move"
if operands[0].is_a? ConstPoolEntry
if operands[0].size == 16
@@ -1102,18 +1045,22 @@ class Instruction
$asm.puts "sts pr, #{sh4Operands(operands)}"
when "memfence"
$asm.puts "synco"
- when "pop"
- if operands[0].sh4Operand == "pr"
- $asm.puts "lds.l @r15+, #{sh4Operands(operands)}"
- else
- $asm.puts "mov.l @r15+, #{sh4Operands(operands)}"
- end
- when "push"
- if operands[0].sh4Operand == "pr"
- $asm.puts "sts.l #{sh4Operands(operands)}, @-r15"
- else
- $asm.puts "mov.l #{sh4Operands(operands)}, @-r15"
- end
+ when "popCalleeSaves"
+ $asm.puts "mov.l @r15+, r8"
+ $asm.puts "mov.l @r15+, r9"
+ $asm.puts "mov.l @r15+, r10"
+ $asm.puts "mov.l @r15+, r11"
+ $asm.puts "mov.l @r15+, r13"
+ $asm.puts "lds.l @r15+, pr"
+ $asm.puts "mov.l @r15+, r14"
+ when "pushCalleeSaves"
+ $asm.puts "mov.l r14, @-r15"
+ $asm.puts "sts.l pr, @-r15"
+ $asm.puts "mov.l r13, @-r15"
+ $asm.puts "mov.l r11, @-r15"
+ $asm.puts "mov.l r10, @-r15"
+ $asm.puts "mov.l r9, @-r15"
+ $asm.puts "mov.l r8, @-r15"
when "break"
# This special opcode always generates an illegal instruction exception.
$asm.puts ".word 0xfffd"
diff --git a/Source/JavaScriptCore/offlineasm/transform.rb b/Source/JavaScriptCore/offlineasm/transform.rb
index 84dd0413b..302971eb7 100644
--- a/Source/JavaScriptCore/offlineasm/transform.rb
+++ b/Source/JavaScriptCore/offlineasm/transform.rb
@@ -423,11 +423,6 @@ class Immediate
end
end
-class StringLiteral
- def validate
- end
-end
-
class RegisterID
def validate
end
@@ -462,13 +457,6 @@ class Instruction
end
end
-class SubImmediates
- def validate
- raise "Invalid operand #{left.dump} to immediate subtraction" unless left.immediateOperand?
- raise "Invalid operand #{right.dump} to immediate subtraction" unless right.immediateOperand?
- end
-end
-
class Error
def validate
end
diff --git a/Source/JavaScriptCore/offlineasm/x86.rb b/Source/JavaScriptCore/offlineasm/x86.rb
index 2e0693726..e47f29561 100644
--- a/Source/JavaScriptCore/offlineasm/x86.rb
+++ b/Source/JavaScriptCore/offlineasm/x86.rb
@@ -1,4 +1,4 @@
-# Copyright (C) 2012, 2014-2016 Apple Inc. All rights reserved.
+# Copyright (C) 2012 Apple Inc. All rights reserved.
# Copyright (C) 2013 Digia Plc. and/or its subsidiary(-ies)
#
# Redistribution and use in source and binary forms, with or without
@@ -24,86 +24,11 @@
require "config"
-# GPR conventions, to match the baseline JIT:
-#
-#
-# On x86-32 bits (windows and non-windows)
-# a0, a1, a2, a3 are only there for ease-of-use of offlineasm; they are not
-# actually considered as such by the ABI and we need to push/pop our arguments
-# on the stack. a0 and a1 are ecx and edx to follow fastcall.
-#
-# eax => t0, a2, r0
-# edx => t1, a1, r1
-# ecx => t2, a0
-# ebx => t3, a3 (callee-save)
-# esi => t4 (callee-save)
-# edi => t5 (callee-save)
-# ebp => cfr
-# esp => sp
-#
-# On x86-64 non-windows
-#
-# rax => t0, r0
-# rdi => a0
-# rsi => t1, a1
-# rdx => t2, a2, r1
-# rcx => t3, a3
-# r8 => t4
-# r10 => t5
-# rbx => csr0 (callee-save, PB, unused in baseline)
-# r12 => csr1 (callee-save)
-# r13 => csr2 (callee-save)
-# r14 => csr3 (callee-save, tagTypeNumber)
-# r15 => csr4 (callee-save, tagMask)
-# rsp => sp
-# rbp => cfr
-# r11 => (scratch)
-#
-# On x86-64 windows
-# Arguments need to be push/pop'd on the stack in addition to being stored in
-# the registers. Also, >8 return types are returned in a weird way.
-#
-# rax => t0, r0
-# rcx => a0
-# rdx => t1, a1, r1
-# r8 => t2, a2
-# r9 => t3, a3
-# r10 => t4
-# rbx => csr0 (callee-save, PB, unused in baseline)
-# rsi => csr1 (callee-save)
-# rdi => csr2 (callee-save)
-# r12 => csr3 (callee-save)
-# r13 => csr4 (callee-save)
-# r14 => csr5 (callee-save, tagTypeNumber)
-# r15 => csr6 (callee-save, tagMask)
-# rsp => sp
-# rbp => cfr
-# r11 => (scratch)
-
def isX64
case $activeBackend
when "X86"
false
- when "X86_WIN"
- false
- when "X86_64"
- true
- when "X86_64_WIN"
- true
- else
- raise "bad value for $activeBackend: #{$activeBackend}"
- end
-end
-
-def isWin
- case $activeBackend
- when "X86"
- false
- when "X86_WIN"
- true
when "X86_64"
- false
- when "X86_64_WIN"
true
else
raise "bad value for $activeBackend: #{$activeBackend}"
@@ -114,230 +39,225 @@ def useX87
case $activeBackend
when "X86"
true
- when "X86_WIN"
- true
when "X86_64"
false
- when "X86_64_WIN"
- false
else
raise "bad value for $activeBackend: #{$activeBackend}"
end
end
-def isCompilingOnWindows
- ENV['OS'] == 'Windows_NT'
-end
-
-def isGCC
- !isCompilingOnWindows
-end
-
-def isMSVC
- isCompilingOnWindows
-end
-
-def isIntelSyntax
- isCompilingOnWindows
-end
-
-def register(name)
- isIntelSyntax ? name : "%" + name
-end
-
-def offsetRegister(off, register)
- isIntelSyntax ? "[#{off} + #{register}]" : "#{off}(#{register})"
-end
-
-def callPrefix
- isIntelSyntax ? "" : "*"
-end
-
-def orderOperands(opA, opB)
- isIntelSyntax ? "#{opB}, #{opA}" : "#{opA}, #{opB}"
-end
-
-def const(c)
- isIntelSyntax ? "#{c}" : "$#{c}"
-end
-
-def getSizeString(kind)
- if !isIntelSyntax
- return ""
- end
-
- size = ""
- case kind
- when :byte
- size = "byte"
- when :half
- size = "word"
- when :int
- size = "dword"
- when :ptr
- size = isX64 ? "qword" : "dword"
- when :double
- size = "qword"
- when :quad
- size = "qword"
- else
- raise "Invalid kind #{kind}"
- end
-
- return size + " " + "ptr" + " ";
-end
-
class SpecialRegister < NoChildren
def x86Operand(kind)
raise unless @name =~ /^r/
raise unless isX64
case kind
when :half
- register(@name + "w")
+ "%" + @name + "w"
when :int
- register(@name + "d")
+ "%" + @name + "d"
when :ptr
- register(@name)
+ "%" + @name
when :quad
- register(@name)
+ "%" + @name
else
raise
end
end
def x86CallOperand(kind)
# Call operands are not allowed to be partial registers.
- "#{callPrefix}#{x86Operand(:quad)}"
+ "*#{x86Operand(:quad)}"
end
end
X64_SCRATCH_REGISTER = SpecialRegister.new("r11")
-def x86GPRName(name, kind)
- case name
- when "eax", "ebx", "ecx", "edx"
- name8 = name[1] + 'l'
- name16 = name[1..2]
- when "esi", "edi", "ebp", "esp"
- name16 = name[1..2]
- name8 = name16 + 'l'
- when "rax", "rbx", "rcx", "rdx"
- raise "bad GPR name #{name} in 32-bit X86" unless isX64
- name8 = name[1] + 'l'
- name16 = name[1..2]
- when "r8", "r9", "r10", "r12", "r13", "r14", "r15"
- raise "bad GPR name #{name} in 32-bit X86" unless isX64
- case kind
- when :half
- return register(name + "w")
- when :int
- return register(name + "d")
- when :ptr
- return register(name)
- when :quad
- return register(name)
- end
- else
- raise "bad GPR name #{name}"
- end
- case kind
- when :byte
- register(name8)
- when :half
- register(name16)
- when :int
- register("e" + name16)
- when :ptr
- register((isX64 ? "r" : "e") + name16)
- when :quad
- isX64 ? register("r" + name16) : raise
- else
- raise "invalid kind #{kind} for GPR #{name} in X86"
- end
-end
-
class RegisterID
def supports8BitOnX86
- case x86GPR
- when "eax", "ebx", "ecx", "edx", "edi", "esi", "ebp", "esp"
+ case name
+ when "t0", "a0", "r0", "t1", "a1", "r1", "t2", "t3", "t4", "t5"
true
- when "r8", "r9", "r10", "r12", "r13", "r14", "r15"
+ when "cfr", "ttnr", "tmr"
false
+ when "t6"
+ isX64
else
raise
end
end
-
- def x86GPR
- if isX64
- case name
- when "t0", "r0"
- "eax"
- when "r1"
- "edx" # t1 = a1 when isWin, t2 = a2 otherwise
- when "a0"
- isWin ? "ecx" : "edi"
- when "t1", "a1"
- isWin ? "edx" : "esi"
- when "t2", "a2"
- isWin ? "r8" : "edx"
- when "t3", "a3"
- isWin ? "r9" : "ecx"
- when "t4"
- isWin ? "r10" : "r8"
- when "t5"
- raise "cannot use register #{name} on X86-64 Windows" unless not isWin
- "r10"
- when "csr0"
- "ebx"
- when "csr1"
- isWin ? "esi" : "r12"
- when "csr2"
- isWin ? "edi" : "r13"
- when "csr3"
- isWin ? "r12" : "r14"
- when "csr4"
- isWin ? "r13" : "r15"
- when "csr5"
- raise "cannot use register #{name} on X86-64" unless isWin
- "r14"
- when "csr6"
- raise "cannot use register #{name} on X86-64" unless isWin
- "r15"
- when "cfr"
- "ebp"
- when "sp"
- "esp"
+
+ def x86Operand(kind)
+ case name
+ when "t0", "a0", "r0"
+ case kind
+ when :byte
+ "%al"
+ when :half
+ "%ax"
+ when :int
+ "%eax"
+ when :ptr
+ isX64 ? "%rax" : "%eax"
+ when :quad
+ isX64 ? "%rax" : raise
else
- raise "cannot use register #{name} on X86"
+ raise "Invalid kind #{kind} for name #{name}"
end
- else
- case name
- when "t0", "r0", "a2"
- "eax"
- when "t1", "r1", "a1"
- "edx"
- when "t2", "a0"
- "ecx"
- when "t3", "a3"
- "ebx"
- when "t4"
- "esi"
- when "t5"
- "edi"
- when "cfr"
- "ebp"
- when "sp"
- "esp"
+ when "t1", "a1", "r1"
+ case kind
+ when :byte
+ "%dl"
+ when :half
+ "%dx"
+ when :int
+ "%edx"
+ when :ptr
+ isX64 ? "%rdx" : "%edx"
+ when :quad
+ isX64 ? "%rdx" : raise
+ else
+ raise
+ end
+ when "t2"
+ case kind
+ when :byte
+ "%cl"
+ when :half
+ "%cx"
+ when :int
+ "%ecx"
+ when :ptr
+ isX64 ? "%rcx" : "%ecx"
+ when :quad
+ isX64 ? "%rcx" : raise
+ else
+ raise
+ end
+ when "t3"
+ case kind
+ when :byte
+ "%bl"
+ when :half
+ "%bx"
+ when :int
+ "%ebx"
+ when :ptr
+ isX64 ? "%rbx" : "%ebx"
+ when :quad
+ isX64 ? "%rbx" : raise
+ else
+ raise
+ end
+ when "t4"
+ case kind
+ when :byte
+ "%sil"
+ when :half
+ "%si"
+ when :int
+ "%esi"
+ when :ptr
+ isX64 ? "%rsi" : "%esi"
+ when :quad
+ isX64 ? "%rsi" : raise
+ else
+ raise
end
+ when "cfr"
+ if isX64
+ case kind
+ when :half
+ "%bp"
+ when :int
+ "%ebp"
+ when :ptr
+ "%rbp"
+ when :quad
+ "%rbp"
+ else
+ raise
+ end
+ else
+ case kind
+ when :half
+ "%bp"
+ when :int
+ "%ebp"
+ when :ptr
+ "%ebp"
+ else
+ raise
+ end
+ end
+ when "sp"
+ case kind
+ when :byte
+ "%spl"
+ when :half
+ "%sp"
+ when :int
+ "%esp"
+ when :ptr
+ isX64 ? "%rsp" : "%esp"
+ when :quad
+ isX64 ? "%rsp" : raise
+ else
+ raise
+ end
+ when "t5"
+ case kind
+ when :byte
+ "%dil"
+ when :half
+ "%di"
+ when :int
+ "%edi"
+ when :ptr
+ isX64 ? "%rdi" : "%edi"
+ when :quad
+ isX64 ? "%rdi" : raise
+ end
+ when "t6"
+ raise "Cannot use #{name} in 32-bit X86 at #{codeOriginString}" unless isX64
+ case kind
+ when :half
+ "%r10w"
+ when :int
+ "%r10d"
+ when :ptr
+ "%r10"
+ when :quad
+ "%r10"
+ end
+ when "csr1"
+ raise "Cannot use #{name} in 32-bit X86 at #{codeOriginString}" unless isX64
+ case kind
+ when :half
+ "%r14w"
+ when :int
+ "%r14d"
+ when :ptr
+ "%r14"
+ when :quad
+ "%r14"
+ end
+ when "csr2"
+ raise "Cannot use #{name} in 32-bit X86 at #{codeOriginString}" unless isX64
+ case kind
+ when :half
+ "%r15w"
+ when :int
+ "%r15d"
+ when :ptr
+ "%r15"
+ when :quad
+ "%r15"
+ end
+ else
+ raise "Bad register #{name} for X86 at #{codeOriginString}"
end
end
-
- def x86Operand(kind)
- x86GPRName(x86GPR, kind)
- end
-
def x86CallOperand(kind)
- "#{callPrefix}#{x86Operand(:ptr)}"
+ isX64 ? "*#{x86Operand(:quad)}" : "*#{x86Operand(:ptr)}"
end
end
@@ -347,17 +267,17 @@ class FPRegisterID
raise if useX87
case name
when "ft0", "fa0", "fr"
- register("xmm0")
+ "%xmm0"
when "ft1", "fa1"
- register("xmm1")
+ "%xmm1"
when "ft2", "fa2"
- register("xmm2")
+ "%xmm2"
when "ft3", "fa3"
- register("xmm3")
+ "%xmm3"
when "ft4"
- register("xmm4")
+ "%xmm4"
when "ft5"
- register("xmm5")
+ "%xmm5"
else
raise "Bad register #{name} for X86 at #{codeOriginString}"
end
@@ -377,10 +297,10 @@ class FPRegisterID
def x87Operand(offset)
raise unless useX87
raise unless offset == 0 or offset == 1
- "#{register("st")}(#{x87DefaultStackPosition + offset})"
+ "%st(#{x87DefaultStackPosition + offset})"
end
def x86CallOperand(kind)
- "#{callPrefix}#{x86Operand(kind)}"
+ "*#{x86Operand(kind)}"
end
end
@@ -393,7 +313,7 @@ class Immediate
end
end
def x86Operand(kind)
- "#{const(value)}"
+ "$#{value}"
end
def x86CallOperand(kind)
"#{value}"
@@ -406,13 +326,13 @@ class Address
end
def x86AddressOperand(addressKind)
- "#{offsetRegister(offset.value, base.x86Operand(addressKind))}"
+ "#{offset.value}(#{base.x86Operand(addressKind)})"
end
def x86Operand(kind)
- "#{getSizeString(kind)}#{x86AddressOperand(:ptr)}"
+ x86AddressOperand(:ptr)
end
def x86CallOperand(kind)
- "#{callPrefix}#{x86Operand(kind)}"
+ "*#{x86Operand(kind)}"
end
end
@@ -422,23 +342,15 @@ class BaseIndex
end
def x86AddressOperand(addressKind)
- if !isIntelSyntax
- "#{offset.value}(#{base.x86Operand(addressKind)}, #{index.x86Operand(addressKind)}, #{scale})"
- else
- "#{getSizeString(addressKind)}[#{offset.value} + #{base.x86Operand(addressKind)} + #{index.x86Operand(addressKind)} * #{scale}]"
- end
+ "#{offset.value}(#{base.x86Operand(addressKind)}, #{index.x86Operand(addressKind)}, #{scale})"
end
def x86Operand(kind)
- if !isIntelSyntax
- x86AddressOperand(:ptr)
- else
- "#{getSizeString(kind)}[#{offset.value} + #{base.x86Operand(:ptr)} + #{index.x86Operand(:ptr)} * #{scale}]"
- end
+ x86AddressOperand(:ptr)
end
def x86CallOperand(kind)
- "#{callPrefix}#{x86Operand(kind)}"
+ "*#{x86Operand(kind)}"
end
end
@@ -456,7 +368,7 @@ class AbsoluteAddress
end
def x86CallOperand(kind)
- "#{callPrefix}#{address.value}"
+ "*#{address.value}"
end
end
@@ -467,9 +379,6 @@ class LabelReference
end
class LocalLabelReference
- def x86Operand(kind)
- asmLabel
- end
def x86CallOperand(kind)
asmLabel
end
@@ -514,30 +423,20 @@ class Sequence
return newList
end
- def getModifiedListX86_64_WIN
- getModifiedListX86_64
- end
end
class Instruction
- @@floatingPointCompareImplicitOperand = isIntelSyntax ? "st(0), " : ""
-
def x86Operands(*kinds)
raise unless kinds.size == operands.size
result = []
kinds.size.times {
| idx |
- i = isIntelSyntax ? (kinds.size - idx - 1) : idx
- result << operands[i].x86Operand(kinds[i])
+ result << operands[idx].x86Operand(kinds[idx])
}
result.join(", ")
end
def x86Suffix(kind)
- if isIntelSyntax
- return ""
- end
-
case kind
when :byte
"b"
@@ -578,15 +477,15 @@ class Instruction
def handleX86OpWithNumOperands(opcode, kind, numOperands)
if numOperands == 3
if operands[0] == operands[2]
- $asm.puts "#{opcode} #{orderOperands(operands[1].x86Operand(kind), operands[2].x86Operand(kind))}"
+ $asm.puts "#{opcode} #{operands[1].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
elsif operands[1] == operands[2]
- $asm.puts "#{opcode} #{orderOperands(operands[0].x86Operand(kind), operands[2].x86Operand(kind))}"
+ $asm.puts "#{opcode} #{operands[0].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
else
- $asm.puts "mov#{x86Suffix(kind)} #{orderOperands(operands[0].x86Operand(kind), operands[2].x86Operand(kind))}"
- $asm.puts "#{opcode} #{orderOperands(operands[1].x86Operand(kind), operands[2].x86Operand(kind))}"
+ $asm.puts "mov#{x86Suffix(kind)} #{operands[0].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
+ $asm.puts "#{opcode} #{operands[1].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
end
else
- $asm.puts "#{opcode} #{orderOperands(operands[0].x86Operand(kind), operands[1].x86Operand(kind))}"
+ $asm.puts "#{opcode} #{operands[0].x86Operand(kind)}, #{operands[1].x86Operand(kind)}"
end
end
@@ -595,12 +494,13 @@ class Instruction
end
def handleX86Shift(opcode, kind)
- if operands[0].is_a? Immediate or operands[0].x86GPR == "ecx"
- $asm.puts "#{opcode} #{orderOperands(operands[0].x86Operand(:byte), operands[1].x86Operand(kind))}"
+ if operands[0].is_a? Immediate or operands[0] == RegisterID.forName(nil, "t2")
+ $asm.puts "#{opcode} #{operands[0].x86Operand(:byte)}, #{operands[1].x86Operand(kind)}"
else
- $asm.puts "xchg#{x86Suffix(:ptr)} #{operands[0].x86Operand(:ptr)}, #{x86GPRName("ecx", :ptr)}"
- $asm.puts "#{opcode} #{orderOperands(register("cl"), operands[1].x86Operand(kind))}"
- $asm.puts "xchg#{x86Suffix(:ptr)} #{operands[0].x86Operand(:ptr)}, #{x86GPRName("ecx", :ptr)}"
+ cx = RegisterID.forName(nil, "t2")
+ $asm.puts "xchg#{x86Suffix(:ptr)} #{operands[0].x86Operand(:ptr)}, #{cx.x86Operand(:ptr)}"
+ $asm.puts "#{opcode} %cl, #{operands[1].x86Operand(kind)}"
+ $asm.puts "xchg#{x86Suffix(:ptr)} #{operands[0].x86Operand(:ptr)}, #{cx.x86Operand(:ptr)}"
end
end
@@ -610,9 +510,9 @@ class Instruction
else
case mode
when :normal
- $asm.puts "ucomisd #{orderOperands(operands[1].x86Operand(:double), operands[0].x86Operand(:double))}"
+ $asm.puts "ucomisd #{operands[1].x86Operand(:double)}, #{operands[0].x86Operand(:double)}"
when :reverse
- $asm.puts "ucomisd #{orderOperands(operands[0].x86Operand(:double), operands[1].x86Operand(:double))}"
+ $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
else
raise mode.inspect
end
@@ -622,11 +522,11 @@ class Instruction
def handleX86IntCompare(opcodeSuffix, kind)
if operands[0].is_a? Immediate and operands[0].value == 0 and operands[1].is_a? RegisterID and (opcodeSuffix == "e" or opcodeSuffix == "ne")
- $asm.puts "test#{x86Suffix(kind)} #{orderOperands(operands[1].x86Operand(kind), operands[1].x86Operand(kind))}"
+ $asm.puts "test#{x86Suffix(kind)} #{operands[1].x86Operand(kind)}, #{operands[1].x86Operand(kind)}"
elsif operands[1].is_a? Immediate and operands[1].value == 0 and operands[0].is_a? RegisterID and (opcodeSuffix == "e" or opcodeSuffix == "ne")
- $asm.puts "test#{x86Suffix(kind)} #{orderOperands(operands[0].x86Operand(kind), operands[0].x86Operand(kind))}"
+ $asm.puts "test#{x86Suffix(kind)} #{operands[0].x86Operand(kind)}, #{operands[0].x86Operand(kind)}"
else
- $asm.puts "cmp#{x86Suffix(kind)} #{orderOperands(operands[1].x86Operand(kind), operands[0].x86Operand(kind))}"
+ $asm.puts "cmp#{x86Suffix(kind)} #{operands[1].x86Operand(kind)}, #{operands[0].x86Operand(kind)}"
end
end
@@ -638,20 +538,12 @@ class Instruction
def handleX86Set(setOpcode, operand)
if operand.supports8BitOnX86
$asm.puts "#{setOpcode} #{operand.x86Operand(:byte)}"
- if !isIntelSyntax
- $asm.puts "movzbl #{orderOperands(operand.x86Operand(:byte), operand.x86Operand(:int))}"
- else
- $asm.puts "movzx #{orderOperands(operand.x86Operand(:byte), operand.x86Operand(:int))}"
- end
+ $asm.puts "movzbl #{operand.x86Operand(:byte)}, #{operand.x86Operand(:int)}"
else
- ax = RegisterID.new(nil, "r0")
+ ax = RegisterID.new(nil, "t0")
$asm.puts "xchg#{x86Suffix(:ptr)} #{operand.x86Operand(:ptr)}, #{ax.x86Operand(:ptr)}"
- $asm.puts "#{setOpcode} #{ax.x86Operand(:byte)}"
- if !isIntelSyntax
- $asm.puts "movzbl #{ax.x86Operand(:byte)}, #{ax.x86Operand(:int)}"
- else
- $asm.puts "movzx #{ax.x86Operand(:int)}, #{ax.x86Operand(:byte)}"
- end
+ $asm.puts "#{setOpcode} %al"
+ $asm.puts "movzbl %al, %eax"
$asm.puts "xchg#{x86Suffix(:ptr)} #{operand.x86Operand(:ptr)}, #{ax.x86Operand(:ptr)}"
end
end
@@ -676,10 +568,10 @@ class Instruction
if value.is_a? RegisterID
$asm.puts "test#{x86Suffix(kind)} #{value.x86Operand(kind)}, #{value.x86Operand(kind)}"
else
- $asm.puts "cmp#{x86Suffix(kind)} #{orderOperands(const(0), value.x86Operand(kind))}"
+ $asm.puts "cmp#{x86Suffix(kind)} $0, #{value.x86Operand(kind)}"
end
else
- $asm.puts "test#{x86Suffix(kind)} #{orderOperands(mask.x86Operand(kind), value.x86Operand(kind))}"
+ $asm.puts "test#{x86Suffix(kind)} #{mask.x86Operand(kind)}, #{value.x86Operand(kind)}"
end
end
@@ -709,7 +601,7 @@ class Instruction
def handleX86SubBranch(branchOpcode, kind)
if operands.size == 4 and operands[1] == operands[2]
$asm.puts "neg#{x86Suffix(kind)} #{operands[2].x86Operand(kind)}"
- $asm.puts "add#{x86Suffix(kind)} #{orderOperands(operands[0].x86Operand(kind), operands[2].x86Operand(kind))}"
+ $asm.puts "add#{x86Suffix(kind)} #{operands[0].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
else
handleX86OpWithNumOperands("sub#{x86Suffix(kind)}", kind, operands.size - 1)
end
@@ -727,29 +619,25 @@ class Instruction
def handleX86Add(kind)
if operands.size == 3 and operands[1] == operands[2]
unless Immediate.new(nil, 0) == operands[0]
- $asm.puts "add#{x86Suffix(kind)} #{orderOperands(operands[0].x86Operand(kind), operands[2].x86Operand(kind))}"
+ $asm.puts "add#{x86Suffix(kind)} #{operands[0].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
end
elsif operands.size == 3 and operands[0].is_a? Immediate
raise unless operands[1].is_a? RegisterID
raise unless operands[2].is_a? RegisterID
if operands[0].value == 0
unless operands[1] == operands[2]
- $asm.puts "mov#{x86Suffix(kind)} #{orderOperands(operands[1].x86Operand(kind), operands[2].x86Operand(kind))}"
+ $asm.puts "mov#{x86Suffix(kind)} #{operands[1].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
end
else
- $asm.puts "lea#{x86Suffix(kind)} #{orderOperands(offsetRegister(operands[0].value, operands[1].x86Operand(kind)), operands[2].x86Operand(kind))}"
+ $asm.puts "lea#{x86Suffix(kind)} #{operands[0].value}(#{operands[1].x86Operand(kind)}), #{operands[2].x86Operand(kind)}"
end
elsif operands.size == 3 and operands[0].is_a? RegisterID
raise unless operands[1].is_a? RegisterID
raise unless operands[2].is_a? RegisterID
if operands[0] == operands[2]
- $asm.puts "add#{x86Suffix(kind)} #{orderOperands(operands[1].x86Operand(kind), operands[2].x86Operand(kind))}"
+ $asm.puts "add#{x86Suffix(kind)} #{operands[1].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
else
- if !isIntelSyntax
- $asm.puts "lea#{x86Suffix(kind)} (#{operands[0].x86Operand(kind)}, #{operands[1].x86Operand(kind)}), #{operands[2].x86Operand(kind)}"
- else
- $asm.puts "lea#{x86Suffix(kind)} #{operands[2].x86Operand(kind)}, [#{operands[0].x86Operand(kind)} + #{operands[1].x86Operand(kind)}]"
- end
+ $asm.puts "lea#{x86Suffix(kind)} (#{operands[0].x86Operand(kind)}, #{operands[1].x86Operand(kind)}), #{operands[2].x86Operand(kind)}"
end
else
unless Immediate.new(nil, 0) == operands[0]
@@ -761,7 +649,7 @@ class Instruction
def handleX86Sub(kind)
if operands.size == 3 and operands[1] == operands[2]
$asm.puts "neg#{x86Suffix(kind)} #{operands[2].x86Operand(kind)}"
- $asm.puts "add#{x86Suffix(kind)} #{orderOperands(operands[0].x86Operand(kind), operands[2].x86Operand(kind))}"
+ $asm.puts "add#{x86Suffix(kind)} #{operands[0].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
else
handleX86Op("sub#{x86Suffix(kind)}", kind)
end
@@ -777,20 +665,6 @@ class Instruction
end
end
- def handleX86Peek()
- sp = RegisterID.new(nil, "sp")
- opA = offsetRegister(operands[0].value * x86Bytes(:ptr), sp.x86Operand(:ptr))
- opB = operands[1].x86Operand(:ptr)
- $asm.puts "mov#{x86Suffix(:ptr)} #{orderOperands(opA, opB)}"
- end
-
- def handleX86Poke()
- sp = RegisterID.new(nil, "sp")
- opA = operands[0].x86Operand(:ptr)
- opB = offsetRegister(operands[1].value * x86Bytes(:ptr), sp.x86Operand(:ptr))
- $asm.puts "mov#{x86Suffix(:ptr)} #{orderOperands(opA, opB)}"
- end
-
def handleMove
if Immediate.new(nil, 0) == operands[0] and operands[1].is_a? RegisterID
if isX64
@@ -806,22 +680,22 @@ class Instruction
end
end
end
-
+
def handleX87Compare(mode)
case mode
when :normal
if (operands[0].x87DefaultStackPosition == 0)
- $asm.puts "fucomi #{@@floatingPointCompareImplicitOperand}#{operands[1].x87Operand(0)}"
+ $asm.puts "fucomi #{operands[1].x87Operand(0)}"
else
$asm.puts "fld #{operands[0].x87Operand(0)}"
- $asm.puts "fucomip #{@@floatingPointCompareImplicitOperand}#{operands[1].x87Operand(1)}"
+ $asm.puts "fucomip #{operands[1].x87Operand(1)}"
end
when :reverse
if (operands[1].x87DefaultStackPosition == 0)
- $asm.puts "fucomi #{@@floatingPointCompareImplicitOperand}#{operands[0].x87Operand(0)}"
+ $asm.puts "fucomi #{operands[0].x87Operand(0)}"
else
$asm.puts "fld #{operands[1].x87Operand(0)}"
- $asm.puts "fucomip #{@@floatingPointCompareImplicitOperand}#{operands[0].x87Operand(1)}"
+ $asm.puts "fucomip #{operands[0].x87Operand(1)}"
end
else
raise mode.inspect
@@ -830,16 +704,12 @@ class Instruction
def handleX87BinOp(opcode, opcodereverse)
if (operands[1].x87DefaultStackPosition == 0)
- $asm.puts "#{opcode} #{orderOperands(operands[0].x87Operand(0), register("st"))}"
+ $asm.puts "#{opcode} #{operands[0].x87Operand(0)}, %st"
elsif (operands[0].x87DefaultStackPosition == 0)
- if !isIntelSyntax
- $asm.puts "#{opcodereverse} #{register("st")}, #{operands[1].x87Operand(0)}"
- else
- $asm.puts "#{opcode} #{operands[1].x87Operand(0)}, #{register("st")}"
- end
+ $asm.puts "#{opcodereverse} %st, #{operands[1].x87Operand(0)}"
else
$asm.puts "fld #{operands[0].x87Operand(0)}"
- $asm.puts "#{opcodereverse}p #{orderOperands(register("st"), operands[1].x87Operand(1))}"
+ $asm.puts "#{opcodereverse}p %st, #{operands[1].x87Operand(1)}"
end
end
@@ -847,26 +717,15 @@ class Instruction
raise unless $activeBackend == "X86"
lowerX86Common
end
-
- def lowerX86_WIN
- raise unless $activeBackend == "X86_WIN"
- lowerX86Common
- end
def lowerX86_64
raise unless $activeBackend == "X86_64"
lowerX86Common
end
-
- def lowerX86_64_WIN
- raise unless $activeBackend == "X86_64_WIN"
- lowerX86Common
- end
-
+
def lowerX86Common
$asm.codeOrigin codeOriginString if $enableCodeOriginComments
$asm.annotation annotation if $enableInstrAnnotations
- $asm.debugAnnotation codeOrigin.debugDirective if $enableDebugAnnotations
case opcode
when "addi"
@@ -876,13 +735,13 @@ class Instruction
when "addq"
handleX86Add(:quad)
when "andi"
- handleX86Op("and#{x86Suffix(:int)}", :int)
+ handleX86Op("andl", :int)
when "andp"
handleX86Op("and#{x86Suffix(:ptr)}", :ptr)
when "andq"
handleX86Op("and#{x86Suffix(:quad)}", :quad)
when "lshifti"
- handleX86Shift("sal#{x86Suffix(:int)}", :int)
+ handleX86Shift("sall", :int)
when "lshiftp"
handleX86Shift("sal#{x86Suffix(:ptr)}", :ptr)
when "lshiftq"
@@ -894,27 +753,27 @@ class Instruction
when "mulq"
handleX86Mul(:quad)
when "negi"
- $asm.puts "neg#{x86Suffix(:int)} #{x86Operands(:int)}"
+ $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 "not#{x86Suffix(:int)} #{x86Operands(:int)}"
+ $asm.puts "notl #{x86Operands(:int)}"
when "ori"
- handleX86Op("or#{x86Suffix(:int)}", :int)
+ handleX86Op("orl", :int)
when "orp"
handleX86Op("or#{x86Suffix(:ptr)}", :ptr)
when "orq"
handleX86Op("or#{x86Suffix(:quad)}", :quad)
when "rshifti"
- handleX86Shift("sar#{x86Suffix(:int)}", :int)
+ handleX86Shift("sarl", :int)
when "rshiftp"
handleX86Shift("sar#{x86Suffix(:ptr)}", :ptr)
when "rshiftq"
handleX86Shift("sar#{x86Suffix(:quad)}", :quad)
when "urshifti"
- handleX86Shift("shr#{x86Suffix(:int)}", :int)
+ handleX86Shift("shrl", :int)
when "urshiftp"
handleX86Shift("shr#{x86Suffix(:ptr)}", :ptr)
when "urshiftq"
@@ -926,52 +785,36 @@ class Instruction
when "subq"
handleX86Sub(:quad)
when "xori"
- handleX86Op("xor#{x86Suffix(:int)}", :int)
+ handleX86Op("xorl", :int)
when "xorp"
handleX86Op("xor#{x86Suffix(:ptr)}", :ptr)
when "xorq"
handleX86Op("xor#{x86Suffix(:quad)}", :quad)
when "loadi", "storei"
- $asm.puts "mov#{x86Suffix(:int)} #{x86Operands(:int, :int)}"
+ $asm.puts "movl #{x86Operands(:int, :int)}"
when "loadis"
if isX64
- if !isIntelSyntax
- $asm.puts "movslq #{x86Operands(:int, :quad)}"
- else
- $asm.puts "movsxd #{x86Operands(:int, :quad)}"
- end
+ $asm.puts "movslq #{x86Operands(:int, :quad)}"
else
- $asm.puts "mov#{x86Suffix(:int)} #{x86Operands(:int, :int)}"
+ $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"
- if !isIntelSyntax
- $asm.puts "movzbl #{orderOperands(operands[0].x86Operand(:byte), operands[1].x86Operand(:int))}"
- else
- $asm.puts "movzx #{orderOperands(operands[0].x86Operand(:byte), operands[1].x86Operand(:int))}"
- end
+ $asm.puts "movzbl #{operands[0].x86Operand(:byte)}, #{operands[1].x86Operand(:int)}"
when "loadbs"
$asm.puts "movsbl #{operands[0].x86Operand(:byte)}, #{operands[1].x86Operand(:int)}"
when "loadh"
- if !isIntelSyntax
- $asm.puts "movzwl #{orderOperands(operands[0].x86Operand(:half), operands[1].x86Operand(:int))}"
- else
- $asm.puts "movzx #{orderOperands(operands[0].x86Operand(:half), operands[1].x86Operand(:int))}"
- end
+ $asm.puts "movzwl #{operands[0].x86Operand(:half)}, #{operands[1].x86Operand(:int)}"
when "loadhs"
$asm.puts "movswl #{operands[0].x86Operand(:half)}, #{operands[1].x86Operand(:int)}"
when "storeb"
- $asm.puts "mov#{x86Suffix(:byte)} #{x86Operands(:byte, :byte)}"
+ $asm.puts "movb #{x86Operands(:byte, :byte)}"
when "loadd"
if useX87
- if !isIntelSyntax
- $asm.puts "fldl #{operands[0].x86Operand(:double)}"
- else
- $asm.puts "fld #{operands[0].x86Operand(:double)}"
- end
+ $asm.puts "fldl #{operands[0].x86Operand(:double)}"
$asm.puts "fstp #{operands[1].x87Operand(1)}"
else
$asm.puts "movsd #{x86Operands(:double, :double)}"
@@ -990,14 +833,10 @@ class Instruction
when "stored"
if useX87
if (operands[0].x87DefaultStackPosition == 0)
- $asm.puts "fst#{x86Suffix(:int)} #{operands[1].x86Operand(:double)}"
+ $asm.puts "fstl #{operands[1].x86Operand(:double)}"
else
$asm.puts "fld #{operands[0].x87Operand(0)}"
- if !isIntelSyntax
- $asm.puts "fstpl #{operands[1].x86Operand(:double)}"
- else
- $asm.puts "fstp #{operands[1].x86Operand(:double)}"
- end
+ $asm.puts "fstpl #{operands[1].x86Operand(:double)}"
end
else
$asm.puts "movsd #{x86Operands(:double, :double)}"
@@ -1037,17 +876,17 @@ class Instruction
when "ci2d"
if useX87
sp = RegisterID.new(nil, "sp")
- $asm.puts "mov#{x86Suffix(:int)} #{orderOperands(operands[0].x86Operand(:int), offsetRegister(-4, sp.x86Operand(:ptr)))}"
- $asm.puts "fild#{x86Suffix(:ptr)} #{getSizeString(:ptr)}#{offsetRegister(-4, sp.x86Operand(:ptr))}"
+ $asm.puts "movl #{operands[0].x86Operand(:int)}, -4(#{sp.x86Operand(:ptr)})"
+ $asm.puts "fildl -4(#{sp.x86Operand(:ptr)})"
$asm.puts "fstp #{operands[1].x87Operand(1)}"
else
- $asm.puts "cvtsi2sd #{orderOperands(operands[0].x86Operand(:int), operands[1].x86Operand(:double))}"
+ $asm.puts "cvtsi2sd #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:double)}"
end
when "bdeq"
if useX87
handleX87Compare(:normal)
else
- $asm.puts "ucomisd #{orderOperands(operands[0].x86Operand(:double), operands[1].x86Operand(:double))}"
+ $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
end
if operands[0] == operands[1]
# This is just a jump ordered, which is a jnp.
@@ -1074,7 +913,7 @@ class Instruction
if useX87
handleX87Compare(:normal)
else
- $asm.puts "ucomisd #{orderOperands(operands[0].x86Operand(:double), operands[1].x86Operand(:double))}"
+ $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
end
if operands[0] == operands[1]
# This is just a jump unordered, which is a jp.
@@ -1113,18 +952,18 @@ class Instruction
$asm.puts "fistl -4(#{sp.x86Operand(:ptr)})"
else
$asm.puts "fld #{operands[0].x87Operand(0)}"
- $asm.puts "fistp#{x86Suffix(:ptr)} #{getSizeString(:ptr)}#{offsetRegister(-4, sp.x86Operand(:ptr))}"
+ $asm.puts "fistpl -4(#{sp.x86Operand(:ptr)})"
end
- $asm.puts "mov#{x86Suffix(:int)} #{orderOperands(offsetRegister(-4, sp.x86Operand(:ptr)), operands[1].x86Operand(:int))}"
- $asm.puts "test#{x86Suffix(:int)} #{operands[1].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
+ $asm.puts "movl -4(#{sp.x86Operand(:ptr)}), #{operands[1].x86Operand(:int)}"
+ $asm.puts "testl #{operands[1].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
$asm.puts "je #{operands[2].asmLabel}"
- $asm.puts "fild#{x86Suffix(:int)} #{getSizeString(:int)}#{offsetRegister(-4, sp.x86Operand(:ptr))}"
- $asm.puts "fucomip #{@@floatingPointCompareImplicitOperand}#{operands[0].x87Operand(1)}"
+ $asm.puts "fildl -4(#{sp.x86Operand(:ptr)})"
+ $asm.puts "fucomip #{operands[0].x87Operand(1)}"
$asm.puts "jp #{operands[2].asmLabel}"
$asm.puts "jne #{operands[2].asmLabel}"
else
$asm.puts "cvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
- $asm.puts "test#{x86Suffix(:int)} #{operands[1].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
+ $asm.puts "testl #{operands[1].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
$asm.puts "je #{operands[2].asmLabel}"
$asm.puts "cvtsi2sd #{operands[1].x86Operand(:int)}, %xmm7"
$asm.puts "ucomisd #{operands[0].x86Operand(:double)}, %xmm7"
@@ -1148,16 +987,36 @@ class Instruction
| op |
$asm.puts "push #{op.x86Operand(:ptr)}"
}
+ when "popCalleeSaves"
+ if isX64
+ $asm.puts "pop %rbx"
+ $asm.puts "pop %r15"
+ $asm.puts "pop %r14"
+ $asm.puts "pop %r13"
+ $asm.puts "pop %r12"
+ else
+ $asm.puts "pop %ebx"
+ $asm.puts "pop %edi"
+ $asm.puts "pop %esi"
+ end
+ when "pushCalleeSaves"
+ if isX64
+ $asm.puts "push %r12"
+ $asm.puts "push %r13"
+ $asm.puts "push %r14"
+ $asm.puts "push %r15"
+ $asm.puts "push %rbx"
+ else
+ $asm.puts "push %esi"
+ $asm.puts "push %edi"
+ $asm.puts "push %ebx"
+ end
when "move"
handleMove
when "sxi2q"
- if !isIntelSyntax
- $asm.puts "movslq #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:quad)}"
- else
- $asm.puts "movsxd #{orderOperands(operands[0].x86Operand(:int), operands[1].x86Operand(:quad))}"
- end
+ $asm.puts "movslq #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:quad)}"
when "zxi2q"
- $asm.puts "mov#{x86Suffix(:int)} #{orderOperands(operands[0].x86Operand(:int), operands[1].x86Operand(:int))}"
+ $asm.puts "movl #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
when "nop"
$asm.puts "nop"
when "bieq"
@@ -1267,25 +1126,25 @@ class Instruction
when "jmp"
$asm.puts "jmp #{operands[0].x86CallOperand(:ptr)}"
when "baddio"
- handleX86OpBranch("add#{x86Suffix(:int)}", "jo", :int)
+ handleX86OpBranch("addl", "jo", :int)
when "baddpo"
handleX86OpBranch("add#{x86Suffix(:ptr)}", "jo", :ptr)
when "baddqo"
handleX86OpBranch("add#{x86Suffix(:quad)}", "jo", :quad)
when "baddis"
- handleX86OpBranch("add#{x86Suffix(:int)}", "js", :int)
+ handleX86OpBranch("addl", "js", :int)
when "baddps"
handleX86OpBranch("add#{x86Suffix(:ptr)}", "js", :ptr)
when "baddqs"
handleX86OpBranch("add#{x86Suffix(:quad)}", "js", :quad)
when "baddiz"
- handleX86OpBranch("add#{x86Suffix(:int)}", "jz", :int)
+ handleX86OpBranch("addl", "jz", :int)
when "baddpz"
handleX86OpBranch("add#{x86Suffix(:ptr)}", "jz", :ptr)
when "baddqz"
handleX86OpBranch("add#{x86Suffix(:quad)}", "jz", :quad)
when "baddinz"
- handleX86OpBranch("add#{x86Suffix(:int)}", "jnz", :int)
+ handleX86OpBranch("addl", "jnz", :int)
when "baddpnz"
handleX86OpBranch("add#{x86Suffix(:ptr)}", "jnz", :ptr)
when "baddqnz"
@@ -1299,13 +1158,13 @@ class Instruction
when "bsubinz"
handleX86SubBranch("jnz", :int)
when "bmulio"
- handleX86OpBranch("imul#{x86Suffix(:int)}", "jo", :int)
+ handleX86OpBranch("imull", "jo", :int)
when "bmulis"
- handleX86OpBranch("imul#{x86Suffix(:int)}", "js", :int)
+ handleX86OpBranch("imull", "js", :int)
when "bmuliz"
- handleX86OpBranch("imul#{x86Suffix(:int)}", "jz", :int)
+ handleX86OpBranch("imull", "jz", :int)
when "bmulinz"
- handleX86OpBranch("imul#{x86Suffix(:int)}", "jnz", :int)
+ handleX86OpBranch("imull", "jnz", :int)
when "borio"
handleX86OpBranch("orl", "jo", :int)
when "boris"
@@ -1315,19 +1174,15 @@ class Instruction
when "borinz"
handleX86OpBranch("orl", "jnz", :int)
when "break"
- $asm.puts "int #{const(3)}"
+ $asm.puts "int $3"
when "call"
if useX87
2.times {
| offset |
- $asm.puts "ffree #{register("st")}(#{offset})"
+ $asm.puts "ffree %st(#{offset})"
}
end
- op = operands[0].x86CallOperand(:ptr)
- if operands[0].is_a? LabelReference
- operands[0].used
- end
- $asm.puts "call #{op}"
+ $asm.puts "call #{operands[0].x86CallOperand(:ptr)}"
when "ret"
$asm.puts "ret"
when "cieq"
@@ -1435,19 +1290,21 @@ class Instruction
when "tbnz"
handleX86SetTest("setnz", :byte)
when "peek"
- handleX86Peek()
+ sp = RegisterID.new(nil, "sp")
+ $asm.puts "mov#{x86Suffix(:ptr)} #{operands[0].value * x86Bytes(:ptr)}(#{sp.x86Operand(:ptr)}), #{operands[1].x86Operand(:ptr)}"
when "poke"
- handleX86Poke()
+ sp = RegisterID.new(nil, "sp")
+ $asm.puts "mov#{x86Suffix(:ptr)} #{operands[0].x86Operand(:ptr)}, #{operands[1].value * x86Bytes(:ptr)}(#{sp.x86Operand(:ptr)})"
when "cdqi"
$asm.puts "cdq"
when "idivi"
- $asm.puts "idiv#{x86Suffix(:int)} #{operands[0].x86Operand(:int)}"
+ $asm.puts "idivl #{operands[0].x86Operand(:int)}"
when "fii2d"
if useX87
sp = RegisterID.new(nil, "sp")
- $asm.puts "mov#{x86Suffix(:int)} #{orderOperands(operands[0].x86Operand(:int), offsetRegister(-8, sp.x86Operand(:ptr)))}"
- $asm.puts "mov#{x86Suffix(:int)} #{orderOperands(operands[1].x86Operand(:int), offsetRegister(-4, sp.x86Operand(:ptr)))}"
- $asm.puts "fld#{x86Suffix(:ptr)} #{getSizeString(:double)}#{offsetRegister(-8, sp.x86Operand(:ptr))}"
+ $asm.puts "movl #{operands[0].x86Operand(:int)}, -8(#{sp.x86Operand(:ptr)})"
+ $asm.puts "movl #{operands[1].x86Operand(:int)}, -4(#{sp.x86Operand(:ptr)})"
+ $asm.puts "fldl -8(#{sp.x86Operand(:ptr)})"
$asm.puts "fstp #{operands[2].x87Operand(1)}"
else
$asm.puts "movd #{operands[0].x86Operand(:int)}, #{operands[2].x86Operand(:double)}"
@@ -1459,13 +1316,13 @@ class Instruction
if useX87
sp = RegisterID.new(nil, "sp")
if (operands[0].x87DefaultStackPosition == 0)
- $asm.puts "fst#{x86Suffix(:ptr)} #{getSizeString(:double)}#{offsetRegister(-8, sp.x86Operand(:ptr))}"
+ $asm.puts "fstl -8(#{sp.x86Operand(:ptr)})"
else
$asm.puts "fld #{operands[0].x87Operand(0)}"
$asm.puts "fstpl -8(#{sp.x86Operand(:ptr)})"
end
- $asm.puts "mov#{x86Suffix(:int)} #{orderOperands(offsetRegister(-8, sp.x86Operand(:ptr)), operands[1].x86Operand(:int))}"
- $asm.puts "mov#{x86Suffix(:int)} #{orderOperands(offsetRegister(-4, sp.x86Operand(:ptr)), operands[2].x86Operand(:int))}"
+ $asm.puts "movl -8(#{sp.x86Operand(:ptr)}), #{operands[1].x86Operand(:int)}"
+ $asm.puts "movl -4(#{sp.x86Operand(:ptr)}), #{operands[2].x86Operand(:int)}"
else
$asm.puts "movd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
$asm.puts "movsd #{operands[0].x86Operand(:double)}, %xmm7"
@@ -1479,32 +1336,20 @@ class Instruction
$asm.puts "fldl -8(#{sp.x86Operand(:ptr)})"
$asm.puts "fstp #{operands[1].x87Operand(1)}"
else
- if !isIntelSyntax
- $asm.puts "movq #{operands[0].x86Operand(:quad)}, #{operands[1].x86Operand(:double)}"
- else
- # MASM does not accept register operands with movq.
- # Debugging shows that movd actually moves a qword when using MASM.
- $asm.puts "movd #{operands[1].x86Operand(:double)}, #{operands[0].x86Operand(:quad)}"
- end
+ $asm.puts "movq #{operands[0].x86Operand(:quad)}, #{operands[1].x86Operand(:double)}"
end
when "fd2q"
if useX87
sp = RegisterID.new(nil, "sp")
if (operands[0].x87DefaultStackPosition == 0)
- $asm.puts "fst#{x86Suffix(:int)} #{getSizeString(:int)}#{offsetRegister(-8, sp.x86Operand(:ptr))}"
+ $asm.puts "fstl -8(#{sp.x86Operand(:ptr)})"
else
$asm.puts "fld #{operands[0].x87Operand(0)}"
$asm.puts "fstpl -8(#{sp.x86Operand(:ptr)})"
end
$asm.puts "movq -8(#{sp.x86Operand(:ptr)}), #{operands[1].x86Operand(:quad)}"
else
- if !isIntelSyntax
- $asm.puts "movq #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:quad)}"
- else
- # MASM does not accept register operands with movq.
- # Debugging shows that movd actually moves a qword when using MASM.
- $asm.puts "movd #{operands[1].x86Operand(:quad)}, #{operands[0].x86Operand(:double)}"
- end
+ $asm.puts "movq #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:quad)}"
end
when "bo"
$asm.puts "jo #{operands[0].asmLabel}"
@@ -1515,9 +1360,9 @@ class Instruction
when "bnz"
$asm.puts "jnz #{operands[0].asmLabel}"
when "leai"
- $asm.puts "lea#{x86Suffix(:int)} #{orderOperands(operands[0].x86AddressOperand(:int), operands[1].x86Operand(:int))}"
+ $asm.puts "leal #{operands[0].x86AddressOperand(:int)}, #{operands[1].x86Operand(:int)}"
when "leap"
- $asm.puts "lea#{x86Suffix(:ptr)} #{orderOperands(operands[0].x86AddressOperand(:ptr), operands[1].x86Operand(:ptr))}"
+ $asm.puts "lea#{x86Suffix(:ptr)} #{operands[0].x86AddressOperand(:ptr)}, #{operands[1].x86Operand(:ptr)}"
when "memfence"
$asm.puts "mfence"
else