Ignore:
Timestamp:
Nov 2, 2019, 1:12:38 PM (6 years ago)
Author:
[email protected]
Message:

The offline assembler is wrong about which immediates are supported by and/or/xor on ARM64
https://bugs.webkit.org/show_bug.cgi?id=203752

Reviewed by Tadeu Zagallo.

See https://dinfuehr.github.io/blog/encoding-of-immediate-values-on-aarch64/ for the details of which immediates are supported.
This patch is a minimal fix, ideally we should refactor all of the code dealing with immediates in risc.rb, but considering that I don't know ruby and this code is poorly/not tested, I went for the simplest possible fix.

  • offlineasm/arm64.rb:
  • offlineasm/mips.rb:
  • offlineasm/risc.rb:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/offlineasm/arm64.rb

    r251886 r251966  
    215215class Immediate
    216216    def arm64Operand(kind)
    217         raise "Invalid immediate #{value} at #{codeOriginString}" if value < 0 or value > 4095
    218217        "\##{value}"
    219218    end
     
    419418            end
    420419        }
     420
    421421        result = riscLowerMisplacedImmediates(result, ["storeb", "storei", "storep", "storeq"])
    422         result = riscLowerMalformedImmediates(result, 0..4095)
     422
     423        # The rules for which immediates are valid for and/or/xor instructions are fairly involved, see https://dinfuehr.github.io/blog/encoding-of-immediate-values-on-aarch64/
     424        validLogicalImmediates = []
     425        def rotate(value, n, size)
     426            mask = (1 << size) - 1
     427            shiftedValue = value << n
     428            result = (shiftedValue & mask) | ((shiftedValue & ~mask) >> size)
     429            return result
     430        end
     431        def replicate(value, size)
     432            until size == 64 do
     433                value = value | (value << size)
     434                size *= 2
     435            end
     436            return value
     437        end
     438        size = 2
     439        until size > 64 do
     440            for numberOfOnes in 1..(size-1) do
     441                for rotation in 0..(size-1) do
     442                    immediate = 0;
     443                    for i in 0..(numberOfOnes-1) do
     444                        immediate = immediate*2 + 1
     445                    end
     446                    immediate = rotate(immediate, rotation, size)
     447                    immediate = replicate(immediate, size)
     448                    validLogicalImmediates << immediate
     449                end
     450            end
     451            size *= 2
     452        end
     453        result = riscLowerMalformedImmediates(result, 0..4095, validLogicalImmediates)
     454
    423455        result = riscLowerMisplacedAddresses(result)
    424456        result = riscLowerMalformedAddresses(result) {
Note: See TracChangeset for help on using the changeset viewer.