summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/offlineasm
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2015-05-20 09:56:07 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2015-05-20 09:56:07 +0000
commit41386e9cb918eed93b3f13648cbef387e371e451 (patch)
treea97f9d7bd1d9d091833286085f72da9d83fd0606 /Source/JavaScriptCore/offlineasm
parente15dd966d523731101f70ccf768bba12435a0208 (diff)
downloadWebKitGtk-tarball-41386e9cb918eed93b3f13648cbef387e371e451.tar.gz
webkitgtk-2.4.9webkitgtk-2.4.9
Diffstat (limited to 'Source/JavaScriptCore/offlineasm')
-rw-r--r--Source/JavaScriptCore/offlineasm/arm.rb25
-rw-r--r--Source/JavaScriptCore/offlineasm/arm64.rb111
-rw-r--r--Source/JavaScriptCore/offlineasm/asm.rb99
-rw-r--r--Source/JavaScriptCore/offlineasm/ast.rb179
-rw-r--r--Source/JavaScriptCore/offlineasm/backends.rb45
-rw-r--r--Source/JavaScriptCore/offlineasm/cloop.rb72
-rw-r--r--Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb8
-rw-r--r--Source/JavaScriptCore/offlineasm/instructions.rb34
-rw-r--r--Source/JavaScriptCore/offlineasm/mips.rb177
-rw-r--r--Source/JavaScriptCore/offlineasm/parser.rb95
-rw-r--r--Source/JavaScriptCore/offlineasm/registers.rb2
-rw-r--r--Source/JavaScriptCore/offlineasm/self_hash.rb15
-rw-r--r--Source/JavaScriptCore/offlineasm/settings.rb59
-rw-r--r--Source/JavaScriptCore/offlineasm/sh4.rb70
-rw-r--r--Source/JavaScriptCore/offlineasm/transform.rb12
-rw-r--r--Source/JavaScriptCore/offlineasm/x86.rb533
16 files changed, 399 insertions, 1137 deletions
diff --git a/Source/JavaScriptCore/offlineasm/arm.rb b/Source/JavaScriptCore/offlineasm/arm.rb
index 44cfbe5c9..10b339eb6 100644
--- a/Source/JavaScriptCore/offlineasm/arm.rb
+++ b/Source/JavaScriptCore/offlineasm/arm.rb
@@ -69,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}"
@@ -108,8 +106,6 @@ class RegisterID
"lr"
when "sp"
"sp"
- when "pc"
- "pc"
else
raise "Bad register #{name} for ARM at #{codeOriginString}"
end
@@ -339,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)}"
@@ -466,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"
@@ -596,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 3a0d786c8..e0a23ff37 100644
--- a/Source/JavaScriptCore/offlineasm/arm64.rb
+++ b/Source/JavaScriptCore/offlineasm/arm64.rb
@@ -1,5 +1,4 @@
-# Copyright (C) 2011, 2012, 2014 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
@@ -41,14 +40,14 @@ require "risc"
# x1 => t1, a1, r1
# x2 => t2, a2
# x3 => a3
-# x5 => t4
-# x6 => t6
# 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
-# x24 => t5
# x27 => csr1 (tagTypeNumber)
# x28 => csr2 (tagMask)
# x29 => cfr
@@ -114,13 +113,11 @@ class RegisterID
when 't3'
arm64GPRName('x23', kind)
when 't4'
- arm64GPRName('x5', kind)
+ arm64GPRName('x10', kind)
when 't5'
- arm64GPRName('x24', kind)
+ arm64GPRName('x11', kind)
when 't6'
- arm64GPRName('x6', kind)
- when 't7'
- arm64GPRName('x7', kind)
+ arm64GPRName('x12', kind)
when 'cfr'
arm64GPRName('x29', kind)
when 'csr1'
@@ -130,7 +127,7 @@ class RegisterID
when 'sp'
'sp'
when 'lr'
- 'x30'
+ 'lr'
else
raise "Bad register name #{@name} at #{codeOriginString}"
end
@@ -198,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
@@ -263,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
@@ -312,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
@@ -430,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}"
@@ -647,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])
@@ -654,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"
@@ -865,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 88c7d7abb..bf2426399 100644
--- a/Source/JavaScriptCore/offlineasm/asm.rb
+++ b/Source/JavaScriptCore/offlineasm/asm.rb
@@ -47,18 +47,16 @@ class Assembler
@numGlobalLabels = 0
@newlineSpacerState = :none
- @lastlabel = ""
end
-
+
def enterAsm
- @outp.puts "OFFLINE_ASM_BEGIN" if !$emitWinAsm
+ @outp.puts "OFFLINE_ASM_BEGIN"
@state = :asm
end
def leaveAsm
- putsProcEndIfNeeded if $emitWinAsm
putsLastComment
- @outp.puts "OFFLINE_ASM_END" if !$emitWinAsm
+ @outp.puts "OFFLINE_ASM_END"
@state = :cpp
end
@@ -86,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.
@@ -139,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)
@@ -158,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
@@ -206,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
+ @outp.puts(formatDump(" OFFLINE_ASM_LOCAL_LABEL(#{labelName})", lastComment))
end
-
- def self.externLabelReference(labelName)
- if !$emitWinAsm
- "\" LOCAL_REFERENCE(#{labelName}) \""
- else
- "#{labelName}"
- end
- 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)
@@ -256,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
@@ -276,8 +220,6 @@ class Assembler
end
end
-IncludeFile.processIncludeOptions()
-
asmFile = ARGV.shift
offsetsFile = ARGV.shift
outputFlnm = ARGV.shift
@@ -291,11 +233,8 @@ rescue MissingMagicValuesException
exit 0
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
@@ -314,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]
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 e7805dfe4..bf01b59b5 100644
--- a/Source/JavaScriptCore/offlineasm/backends.rb
+++ b/Source/JavaScriptCore/offlineasm/backends.rb
@@ -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,7 +79,7 @@ end
class Label
def lower(name)
- $asm.putsLabel(self.name[1..-1], @global)
+ $asm.putsLabel(self.name[1..-1])
end
end
@@ -126,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
@@ -142,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 04a699814..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,24 +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"
+ 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"
+ when "t1"
"t1"
- when "t2", "a2"
+ when "t2"
"t2"
- when "t3", "a3"
+ when "t3"
"t3"
when "t4"
- "pc"
- when "t5"
- "t5"
+ "rPC"
when "t6"
- "pcBase"
- when "t7"
- "t7"
+ "rBasePC"
when "csr1"
"tagTypeNumber"
when "csr2"
@@ -93,7 +103,7 @@ class RegisterID
when "cfr"
"cfr"
when "lr"
- "lr"
+ "rRetVPC"
when "sp"
"sp"
else
@@ -545,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")
@@ -870,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, "==")
@@ -1092,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
@@ -1117,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
@@ -1142,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/generate_offset_extractor.rb b/Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb
index fc4579c17..81c28632c 100644
--- a/Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb
+++ b/Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb
@@ -34,17 +34,9 @@ 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
diff --git a/Source/JavaScriptCore/offlineasm/instructions.rb b/Source/JavaScriptCore/offlineasm/instructions.rb
index 1d0d8676a..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,19 +275,16 @@ RISC_INSTRUCTIONS =
MIPS_INSTRUCTIONS =
[
- "la",
"movz",
"movn",
"slt",
"sltu",
- "pichdr"
+ "pichdr",
+ "pichdrra"
]
SH4_INSTRUCTIONS =
[
- "flushcp",
- "alignformova",
- "mova",
"shllx",
"shlrx",
"shld",
@@ -308,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
@@ -323,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 cc107ec37..686f58f16 100644
--- a/Source/JavaScriptCore/offlineasm/mips.rb
+++ b/Source/JavaScriptCore/offlineasm/mips.rb
@@ -62,6 +62,7 @@ MIPS_TEMP_GPRS = [SpecialRegister.new("$t5"), SpecialRegister.new("$t6"), Specia
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")
@@ -161,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
#
@@ -508,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 {
@@ -541,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,
@@ -632,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)
@@ -641,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
@@ -667,7 +606,6 @@ class Sequence
}
result = mipsAddPICCode(result)
- result = mipsLowerFarBranchOps(result)
result = mipsLowerSimpleBranchOps(result)
result = riscLowerSimpleBranchOps(result)
result = riscLowerHardBranchOps(result)
@@ -776,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
@@ -856,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"
@@ -924,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])
@@ -945,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"
@@ -1006,8 +954,11 @@ class Instruction
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.puts "move #{MIPS_GPSAVE_REG.mipsOperand}, #{MIPS_GP_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 a122a68c4..3b9c67bed 100644
--- a/Source/JavaScriptCore/offlineasm/parser.rb
+++ b/Source/JavaScriptCore/offlineasm/parser.rb
@@ -41,36 +41,6 @@ class CodeOrigin
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
@@ -165,8 +135,6 @@ def lex(str, fileName)
result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
when /\A[:,\(\)\[\]=\+\-~\|&^*]/
result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
- when /\A".*"/
- result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
else
raise "Lexer error at #{CodeOrigin.new(fileName, lineNumber).to_s}, unexpected sequence #{str[0..20].inspect}"
end
@@ -185,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)
@@ -214,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.
@@ -403,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
@@ -420,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
@@ -448,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
@@ -621,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
@@ -733,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
@@ -742,7 +686,7 @@ 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)
@@ -752,29 +696,6 @@ 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)
@@ -787,8 +708,6 @@ def parse(fileName)
end
def parseHash(fileName)
- parser = Parser.new(IO::read(fileName), 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 168667e0c..94e0767a6 100644
--- a/Source/JavaScriptCore/offlineasm/registers.rb
+++ b/Source/JavaScriptCore/offlineasm/registers.rb
@@ -44,7 +44,7 @@ GPRS =
"r1",
"sp",
"lr",
- "pc",
+
# 64-bit only registers:
"csr1", # tag type number register
"csr2" # tag mask register
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 0241f38d8..a804b29cc 100644
--- a/Source/JavaScriptCore/offlineasm/sh4.rb
+++ b/Source/JavaScriptCore/offlineasm/sh4.rb
@@ -150,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
@@ -468,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
@@ -561,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 = []
@@ -576,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
@@ -616,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
@@ -867,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
@@ -904,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"
@@ -1038,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
@@ -1079,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 8830e3d41..e47f29561 100644
--- a/Source/JavaScriptCore/offlineasm/x86.rb
+++ b/Source/JavaScriptCore/offlineasm/x86.rb
@@ -1,4 +1,4 @@
-# Copyright (C) 2012, 2014 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
@@ -28,12 +28,8 @@ 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
@@ -43,99 +39,33 @@ 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 isWindows
- ENV['OS'] == 'Windows_NT'
-end
-
-def isGCC
- !isWindows
-end
-
-def isMSVC
- isWindows
-end
-
-def isIntelSyntax
- isWindows
-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
@@ -160,75 +90,75 @@ class RegisterID
when "t0", "a0", "r0"
case kind
when :byte
- register("al")
+ "%al"
when :half
- register("ax")
+ "%ax"
when :int
- register("eax")
+ "%eax"
when :ptr
- isX64 ? register("rax") : register("eax")
+ isX64 ? "%rax" : "%eax"
when :quad
- isX64 ? register("rax") : raise
+ isX64 ? "%rax" : raise
else
raise "Invalid kind #{kind} for name #{name}"
end
when "t1", "a1", "r1"
case kind
when :byte
- register("dl")
+ "%dl"
when :half
- register("dx")
+ "%dx"
when :int
- register("edx")
+ "%edx"
when :ptr
- isX64 ? register("rdx") : register("edx")
+ isX64 ? "%rdx" : "%edx"
when :quad
- isX64 ? register("rdx") : raise
+ isX64 ? "%rdx" : raise
else
raise
end
when "t2"
case kind
when :byte
- register("cl")
+ "%cl"
when :half
- register("cx")
+ "%cx"
when :int
- register("ecx")
+ "%ecx"
when :ptr
- isX64 ? register("rcx") : register("ecx")
+ isX64 ? "%rcx" : "%ecx"
when :quad
- isX64 ? register("rcx") : raise
+ isX64 ? "%rcx" : raise
else
raise
end
when "t3"
case kind
when :byte
- register("bl")
+ "%bl"
when :half
- register("bx")
+ "%bx"
when :int
- register("ebx")
+ "%ebx"
when :ptr
- isX64 ? register("rbx") : register("ebx")
+ isX64 ? "%rbx" : "%ebx"
when :quad
- isX64 ? register("rbx") : raise
+ isX64 ? "%rbx" : raise
else
raise
end
when "t4"
case kind
when :byte
- register("dil")
+ "%sil"
when :half
- register("di")
+ "%si"
when :int
- register("edi")
+ "%esi"
when :ptr
- isX64 ? register("rdi") : register("edi")
+ isX64 ? "%rsi" : "%esi"
when :quad
- isX64 ? register("rdi") : raise
+ isX64 ? "%rsi" : raise
else
raise
end
@@ -236,24 +166,24 @@ class RegisterID
if isX64
case kind
when :half
- register("bp")
+ "%bp"
when :int
- register("ebp")
+ "%ebp"
when :ptr
- register("rbp")
+ "%rbp"
when :quad
- register("rbp")
+ "%rbp"
else
raise
end
else
case kind
when :half
- register("bp")
+ "%bp"
when :int
- register("ebp")
+ "%ebp"
when :ptr
- register("ebp")
+ "%ebp"
else
raise
end
@@ -261,85 +191,73 @@ class RegisterID
when "sp"
case kind
when :byte
- register("spl")
+ "%spl"
when :half
- register("sp")
+ "%sp"
when :int
- register("esp")
+ "%esp"
when :ptr
- isX64 ? register("rsp") : register("esp")
+ isX64 ? "%rsp" : "%esp"
when :quad
- isX64 ? register("rsp") : raise
+ isX64 ? "%rsp" : raise
else
raise
end
when "t5"
case kind
when :byte
- register("sil")
+ "%dil"
when :half
- register("si")
+ "%di"
when :int
- register("esi")
+ "%edi"
when :ptr
- isX64 ? register("rsi") : register("esi")
+ isX64 ? "%rdi" : "%edi"
when :quad
- isX64 ? register("rsi") : raise
+ isX64 ? "%rdi" : raise
end
when "t6"
raise "Cannot use #{name} in 32-bit X86 at #{codeOriginString}" unless isX64
case kind
when :half
- register("r8w")
- when :int
- register("r8d")
- when :ptr
- register("r8")
- when :quad
- register("r8")
- end
- when "t7"
- raise "Cannot use #{name} in 32-bit X86 at #{codeOriginString}" unless isX64
- case kind
- when :half
- register("r9w")
+ "%r10w"
when :int
- register("r9d")
+ "%r10d"
when :ptr
- register("r9")
+ "%r10"
when :quad
- register("r9")
+ "%r10"
end
when "csr1"
raise "Cannot use #{name} in 32-bit X86 at #{codeOriginString}" unless isX64
case kind
when :half
- register("r14w")
+ "%r14w"
when :int
- register("r14d")
+ "%r14d"
when :ptr
- register("r14")
+ "%r14"
when :quad
- register("r14")
+ "%r14"
end
when "csr2"
raise "Cannot use #{name} in 32-bit X86 at #{codeOriginString}" unless isX64
case kind
when :half
- register("r15w")
+ "%r15w"
when :int
- register("r15d")
+ "%r15d"
when :ptr
- register("r15")
+ "%r15"
when :quad
- register("r15")
+ "%r15"
end
else
raise "Bad register #{name} for X86 at #{codeOriginString}"
end
end
def x86CallOperand(kind)
- isX64 ? "#{callPrefix}#{x86Operand(:quad)}" : "#{callPrefix}#{x86Operand(:ptr)}"
+ isX64 ? "*#{x86Operand(:quad)}" : "*#{x86Operand(:ptr)}"
end
end
@@ -349,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
@@ -379,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
@@ -395,7 +313,7 @@ class Immediate
end
end
def x86Operand(kind)
- "#{const(value)}"
+ "$#{value}"
end
def x86CallOperand(kind)
"#{value}"
@@ -408,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
@@ -424,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
@@ -458,7 +368,7 @@ class AbsoluteAddress
end
def x86CallOperand(kind)
- "#{callPrefix}#{address.value}"
+ "*#{address.value}"
end
end
@@ -469,9 +379,6 @@ class LabelReference
end
class LocalLabelReference
- def x86Operand(kind)
- asmLabel
- end
def x86CallOperand(kind)
asmLabel
end
@@ -516,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"
@@ -580,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
@@ -598,11 +495,11 @@ class Instruction
def handleX86Shift(opcode, kind)
if operands[0].is_a? Immediate or operands[0] == RegisterID.forName(nil, "t2")
- $asm.puts "#{opcode} #{orderOperands(operands[0].x86Operand(:byte), operands[1].x86Operand(kind))}"
+ $asm.puts "#{opcode} #{operands[0].x86Operand(:byte)}, #{operands[1].x86Operand(kind)}"
else
cx = RegisterID.forName(nil, "t2")
$asm.puts "xchg#{x86Suffix(:ptr)} #{operands[0].x86Operand(:ptr)}, #{cx.x86Operand(:ptr)}"
- $asm.puts "#{opcode} #{orderOperands(register("cl"), operands[1].x86Operand(kind))}"
+ $asm.puts "#{opcode} %cl, #{operands[1].x86Operand(kind)}"
$asm.puts "xchg#{x86Suffix(:ptr)} #{operands[0].x86Operand(:ptr)}, #{cx.x86Operand(:ptr)}"
end
end
@@ -613,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
@@ -625,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
@@ -641,11 +538,7 @@ 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, "t0")
$asm.puts "xchg#{x86Suffix(:ptr)} #{operand.x86Operand(:ptr)}, #{ax.x86Operand(:ptr)}"
@@ -675,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
@@ -708,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
@@ -726,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]
@@ -760,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
@@ -776,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
@@ -805,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
@@ -829,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
@@ -846,22 +717,12 @@ 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
@@ -874,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"
@@ -892,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"
@@ -924,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)}"
@@ -988,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)}"
@@ -1035,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.
@@ -1072,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.
@@ -1111,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"
@@ -1146,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"
@@ -1265,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"
@@ -1297,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"
@@ -1313,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"
@@ -1433,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)}"
@@ -1457,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"
@@ -1477,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}"
@@ -1513,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