Skip to content

Instantly share code, notes, and snippets.

@ssvb
Created June 21, 2022 15:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ssvb/d4ef97039c042d47fc98914b429270a1 to your computer and use it in GitHub Desktop.
Save ssvb/d4ef97039c042d47fc98914b429270a1 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
$data = {}
$func_name = nil
# binutils confuses the sizes of the first and the second arguments
# this function contains a fixup workaround
def fixup_vshll(l)
if l =~ /(.*vshll.u16\s+)d(\d+),\s*q(\d+)(.*)/
reg1 = $2.to_i
reg2 = $3.to_i
sprintf("%sq%d, d%d%s", $1, reg1 / 2, reg2 * 2, $4)
else
l
end
end
File.open(ARGV[0]).each_line {|l|
if l =~ /[0-9a-fA-f]{8} \<(.*)\>/ then
$func_name = $1
$data[$func_name] = [] if !$data.has_key?($func_name)
else
if $func_name && l =~ /\s*\w+\:\s+\w+\s+/ then
$data[$func_name].push(l.strip)
end
end
}
def process_func(func_name, a)
# collect information about labels
labels = {}
label_index = 0
a.each {|l|
next if not l =~ /(\w+)\s+\<([^\+]+).*\>$/
if $2 != func_name then
printf("\n/* %s has an external reference - skipped */\n", func_name)
return
end
if !labels.has_key?($1) then
labels[$1] = label_index
label_index += 1
end
}
# print code
printf("\n.global %s\n", func_name)
printf("%s:\n", func_name)
a.each {|l|
next if not l =~ /\s*(\w+)\:\s+\w+\s+(.*)/
addr = $1
cmd = $2
if labels.has_key?(addr) then
printf("%d:", labels[addr])
end
if cmd =~ /(.*?)(\w+)\s+\<.*\>$/ then
prefix = $1
target_addr = $2
if target_addr.to_i(16) > addr.to_i(16) then
cmd = prefix + labels[target_addr].to_s + "f"
else
cmd = prefix + labels[target_addr].to_s + "b"
end
end
cmd.gsub!(/\s*\;\s*\w+/, "")
printf("\t%s\n", fixup_vshll(cmd))
}
end
printf(".text\n")
printf(".fpu neon\n")
printf(".syntax unified\n\n")
$data.each {|func_name, a|
process_func(func_name, a)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment