diff options
| author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2015-05-20 09:56:07 +0000 |
|---|---|---|
| committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2015-05-20 09:56:07 +0000 |
| commit | 41386e9cb918eed93b3f13648cbef387e371e451 (patch) | |
| tree | a97f9d7bd1d9d091833286085f72da9d83fd0606 /Source/JavaScriptCore/offlineasm | |
| parent | e15dd966d523731101f70ccf768bba12435a0208 (diff) | |
| download | WebKitGtk-tarball-41386e9cb918eed93b3f13648cbef387e371e451.tar.gz | |
webkitgtk-2.4.9webkitgtk-2.4.9
Diffstat (limited to 'Source/JavaScriptCore/offlineasm')
| -rw-r--r-- | Source/JavaScriptCore/offlineasm/arm.rb | 25 | ||||
| -rw-r--r-- | Source/JavaScriptCore/offlineasm/arm64.rb | 111 | ||||
| -rw-r--r-- | Source/JavaScriptCore/offlineasm/asm.rb | 99 | ||||
| -rw-r--r-- | Source/JavaScriptCore/offlineasm/ast.rb | 179 | ||||
| -rw-r--r-- | Source/JavaScriptCore/offlineasm/backends.rb | 45 | ||||
| -rw-r--r-- | Source/JavaScriptCore/offlineasm/cloop.rb | 72 | ||||
| -rw-r--r-- | Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb | 8 | ||||
| -rw-r--r-- | Source/JavaScriptCore/offlineasm/instructions.rb | 34 | ||||
| -rw-r--r-- | Source/JavaScriptCore/offlineasm/mips.rb | 177 | ||||
| -rw-r--r-- | Source/JavaScriptCore/offlineasm/parser.rb | 95 | ||||
| -rw-r--r-- | Source/JavaScriptCore/offlineasm/registers.rb | 2 | ||||
| -rw-r--r-- | Source/JavaScriptCore/offlineasm/self_hash.rb | 15 | ||||
| -rw-r--r-- | Source/JavaScriptCore/offlineasm/settings.rb | 59 | ||||
| -rw-r--r-- | Source/JavaScriptCore/offlineasm/sh4.rb | 70 | ||||
| -rw-r--r-- | Source/JavaScriptCore/offlineasm/transform.rb | 12 | ||||
| -rw-r--r-- | Source/JavaScriptCore/offlineasm/x86.rb | 533 |
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 |
