# 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 # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF # THE POSSIBILITY OF SUCH DAMAGE. require 'config' require 'ast' require 'opt' # This file contains utilities that are useful for implementing a backend # for RISC-like processors (ARM, MIPS, etc). # # Lowering of simple branch ops. For example: # # baddiz foo, bar, baz # # will become: # # addi foo, bar # bz baz # def riscLowerSimpleBranchOps(list) newList = [] list.each { | node | if node.is_a? Instruction annotation = node.annotation case node.opcode when /^b(addi|subi|ori|addp)/ op = $1 branch = "b" + $~.post_match case op when "addi" op = "addis" when "addp" op = "addps" when "subi" op = "subis" when "ori" op = "oris" end newList 1000 # else # true # don't lower anything else, in this example # end # } # # See arm.rb for a different example, in which we lower all BaseIndex addresses # that have non-zero offset, all Address addresses that have large offsets, and # all other addresses (like AbsoluteAddress). # class Node def riscLowerMalformedAddressesRecurse(list, topLevelNode, &block) mapChildren { | subNode | subNode.riscLowerMalformedAddressesRecurse(list, topLevelNode, &block) } end end class Address def riscLowerMalformedAddressesRecurse(list, node, &block) return self if yield node, self tmp = Tmp.new(codeOrigin, :gpr) list