X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/6fe7ccc865dc7d7541b93c5bcaf6368d2c98a174..refs/heads/master:/offlineasm/asm.rb diff --git a/offlineasm/asm.rb b/offlineasm/asm.rb index 12bade0..88c7d7a 100644 --- a/offlineasm/asm.rb +++ b/offlineasm/asm.rb @@ -25,6 +25,7 @@ $: << File.dirname(__FILE__) +require "config" require "backends" require "digest/sha1" require "offsets" @@ -39,16 +40,25 @@ class Assembler @state = :cpp @commentState = :none @comment = nil + @internalComment = nil + @annotation = nil + @codeOrigin = nil + @numLocalLabels = 0 + @numGlobalLabels = 0 + + @newlineSpacerState = :none + @lastlabel = "" end - + def enterAsm - @outp.puts "asm (" + @outp.puts "OFFLINE_ASM_BEGIN" if !$emitWinAsm @state = :asm end def leaveAsm + putsProcEndIfNeeded if $emitWinAsm putsLastComment - @outp.puts ");" + @outp.puts "OFFLINE_ASM_END" if !$emitWinAsm @state = :cpp end @@ -58,17 +68,68 @@ class Assembler leaveAsm end + # Concatenates all the various components of the comment to dump. def lastComment - if @comment - result = "// #{@comment}" - else - result = "" + separator = " " + result = "" + result = "#{@comment}" if @comment + if @annotation and $enableInstrAnnotations + result += separator if result != "" + result += "#{@annotation}" end + if @internalComment + result += separator if result != "" + result += "#{@internalComment}" + end + if @codeOrigin and $enableCodeOriginComments + result += separator if result != "" + result += "#{@codeOrigin}" + end + if result != "" + result = $commentPrefix + " " + result + end + + # Reset all the components that we've just sent to be dumped. @commentState = :none @comment = nil + @annotation = nil + @codeOrigin = nil + @internalComment = nil result end + # Puts a C Statement in the output stream. + def putc(*line) + raise unless @state == :asm + @outp.puts(formatDump(" " + line.join(''), lastComment)) + end + + def formatDump(dumpStr, comment, commentColumns=$preferredCommentStartColumn) + if comment.length > 0 + "%-#{commentColumns}s %s" % [dumpStr, comment] + else + dumpStr + end + end + + # private method for internal use only. + def putAnnotation(text) + raise unless @state == :asm + if $enableInstrAnnotations + @outp.puts text + @annotation = nil + end + end + + def putLocalAnnotation() + putAnnotation " // #{@annotation}" if @annotation + end + + def putGlobalAnnotation() + putsNewlineSpacerIfAppropriate(:annotation) + putAnnotation "// #{@annotation}" if @annotation + end + def putsLastComment comment = lastComment unless comment.empty? @@ -78,7 +139,11 @@ class Assembler def puts(*line) raise unless @state == :asm - @outp.puts("\"\\t" + line.join('') + "\\n\" #{lastComment}") + if !$emitWinAsm + @outp.puts(formatDump(" \"\\t" + line.join('') + "\\n\"", lastComment)) + else + @outp.puts(formatDump(" " + line.join(''), lastComment)) + end end def print(line) @@ -86,42 +151,133 @@ class Assembler @outp.print("\"" + line + "\"") end - def putsLabel(labelName) + def putsNewlineSpacerIfAppropriate(state) + if @newlineSpacerState != state + @outp.puts("\n") + @newlineSpacerState = state + 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) raise unless @state == :asm - @outp.puts("OFFLINE_ASM_GLOBAL_LABEL(#{labelName}) #{lastComment}") + @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 + else + if !$emitWinAsm + @outp.puts(formatDump("OFFLINE_ASM_GLUE_LABEL(#{labelName})", lastComment)) + else + @outp.puts(formatDump(" _#{labelName}:", lastComment)) + end + end + @newlineSpacerState = :none # After a global label, we can use another spacer. end def putsLocalLabel(labelName) raise unless @state == :asm - @outp.puts("LOCAL_LABEL_STRING(#{labelName}) \":\\n\" #{lastComment}") + @numLocalLabels += 1 + @outp.puts("\n") + @internalComment = $enableLabelCountComments ? "Local Label #{@numLocalLabels}" : nil + if !$emitWinAsm + @outp.puts(formatDump(" OFFLINE_ASM_LOCAL_LABEL(#{labelName})", lastComment)) + else + @outp.puts(formatDump(" #{labelName}:", lastComment)) + end end - + + def self.externLabelReference(labelName) + if !$emitWinAsm + "\" LOCAL_REFERENCE(#{labelName}) \"" + else + "#{labelName}" + end + end + def self.labelReference(labelName) - "\" SYMBOL_STRING(#{labelName}) \"" + if !$emitWinAsm + "\" LOCAL_LABEL_STRING(#{labelName}) \"" + else + "_#{labelName}" + end end def self.localLabelReference(labelName) - "\" LOCAL_LABEL_STRING(#{labelName}) \"" + if !$emitWinAsm + "\" LOCAL_LABEL_STRING(#{labelName}) \"" + else + "#{labelName}" + end end - def comment(text) + def self.cLabelReference(labelName) + if /\Allint_op_/.match(labelName) + "op_#{$~.post_match}" # strip opcodes of their llint_ prefix. + else + "#{labelName}" + end + end + + def self.cLocalLabelReference(labelName) + "#{labelName}" + end + + def codeOrigin(text) case @commentState when :none - @comment = text + @codeOrigin = text @commentState = :one when :one - @outp.puts "// #{@comment}" - @outp.puts "// #{text}" - @comment = nil + if $enableCodeOriginComments + @outp.puts " " + $commentPrefix + " #{@codeOrigin}" + @outp.puts " " + $commentPrefix + " #{text}" + end + @codeOrigin = nil @commentState = :many when :many - @outp.puts "// #{text}" + @outp.puts $commentPrefix + " #{text}" if $enableCodeOriginComments else raise end end + + def comment(text) + @comment = text + end + def annotation(text) + @annotation = text + end end +IncludeFile.processIncludeOptions() + asmFile = ARGV.shift offsetsFile = ARGV.shift outputFlnm = ARGV.shift @@ -131,12 +287,15 @@ $stderr.puts "offlineasm: Parsing #{asmFile} and #{offsetsFile} and creating ass begin configurationList = offsetsAndConfigurationIndex(offsetsFile) rescue MissingMagicValuesException - $stderr.puts "offlineasm: No magic values found. Skipping assembly file generation assuming the classic interpreter is enabled." + $stderr.puts "offlineasm: No magic values found. Skipping assembly file generation." exit 0 end +$emitWinAsm = isMSVC ? outputFlnm.index(".asm") != nil : false +$commentPrefix = $emitWinAsm ? ";" : "//" + inputHash = - "// offlineasm input hash: " + parseHash(asmFile) + + $commentPrefix + " offlineasm input hash: " + parseHash(asmFile) + " " + Digest::SHA1.hexdigest(configurationList.map{|v| (v[0] + [v[1]]).join(' ')}.join(' ')) + " " + selfHash @@ -155,11 +314,11 @@ File.open(outputFlnm, "w") { | outp | $output = outp $output.puts inputHash - + $asm = Assembler.new($output) ast = parse(asmFile) - + configurationList.each { | configuration | offsetsList = configuration[0]