diff --git a/.github/workflows/emulated.yml b/.github/workflows/emulated.yml new file mode 100644 index 0000000..621b1e9 --- /dev/null +++ b/.github/workflows/emulated.yml @@ -0,0 +1,49 @@ +name: emulated +on: + - push + - pull_request + +defaults: + run: + shell: bash + +jobs: + # Emulation is incredibly slow and memory demanding. It seems that any + # executable with GHC RTS takes at least 7-8 Gb of RAM, so we can run + # `cabal` or `ghc` on their own, but cannot run them both at the same time, + # striking out `cabal test`. Instead we rely on system packages and invoke + # `ghc --make` manually, and even so `ghc -O` is prohibitively expensive. + emulated: + runs-on: ubuntu-latest + strategy: + fail-fast: true + matrix: + arch: ['s390x', 'ppc64le'] + steps: + - uses: actions/checkout@v3 + - uses: uraimo/run-on-arch-action@v2.7.2 + timeout-minutes: 60 + with: + arch: ${{ matrix.arch }} + distro: ubuntu_rolling + githubToken: ${{ github.token }} + install: | + apt-get update -y + apt-get install -y ghc alex happy + run: | + (cd src/; alex -g Scan.x; happy -ag Parser.y) + # Need to remove mention of the Cabal path module, and then substitutes + # getDataDir |-> return "/pwd/data/" + # version |-> undefined + sed -i '/^import Paths_alex.*$/d' src/Main.hs # + # The nested sed here escapes / into \/ so that the outer sed doesn't + # interpret the forward slashes. You're welcome. + sed -i "s/getDataDir/\(return \"$(pwd | sed 's/\//\\\//g')\\/data\"\)/g" src/Main.hs + sed -i "s/version/undefined/g" src/Main.hs + ghc -XHaskell2010 -XPatternSynonyms -XFlexibleContexts -XMagicHash -XCPP -XNondecreasingIndentation -XScopedTypeVariables -XTupleSections \ + -package array -package containers -package directory \ + -isrc src/Main.hs \ + -o alex + ./alex -g tests/simple.x + ghc -package array tests/simple.hs -o simple + ./simple +RTS -s diff --git a/CHANGELOG.md b/CHANGELOG.md index e6341a0..e8b684c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## Changes in 3.5.2.0 + +* Use `byteSwap16#` and `byteSwap32#` on big-endian architectures instead of + handrolling the implementation. + ## Changes in 3.5.1.0 * Drop generating output for GHC < 6.4. diff --git a/data/AlexTemplate.hs b/data/AlexTemplate.hs index 01f7ac9..8ca8c0a 100644 --- a/data/AlexTemplate.hs +++ b/data/AlexTemplate.hs @@ -44,18 +44,15 @@ data AlexAddr = AlexA# Addr# {-# INLINE alexIndexInt16OffAddr #-} alexIndexInt16OffAddr :: AlexAddr -> Int# -> Int# alexIndexInt16OffAddr (AlexA# arr) off = -#ifdef WORDS_BIGENDIAN - narrow16Int# i - where - i = word2Int# ((high `uncheckedShiftL#` 8#) `or#` low) - high = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#))) - low = int2Word# (ord# (indexCharOffAddr# arr off')) - off' = off *# 2# -#else #if __GLASGOW_HASKELL__ >= 901 - GHC.Exts.int16ToInt# + GHC.Exts.int16ToInt# -- qualified import because it doesn't exist on older GHC's #endif - (indexInt16OffAddr# arr off) +#ifdef WORDS_BIGENDIAN + (GHC.Exts.word16ToInt16# (GHC.Exts.wordToWord16# (GHC.Exts.byteSwap16# (GHC.Exts.word16ToWord# (GHC.Exts.int16ToWord16# +#endif + (indexInt16OffAddr# arr off) +#ifdef WORDS_BIGENDIAN + ))))) #endif #else alexIndexInt16OffAddr = (Data.Array.!) @@ -65,22 +62,15 @@ alexIndexInt16OffAddr = (Data.Array.!) {-# INLINE alexIndexInt32OffAddr #-} alexIndexInt32OffAddr :: AlexAddr -> Int# -> Int# alexIndexInt32OffAddr (AlexA# arr) off = -#ifdef WORDS_BIGENDIAN - narrow32Int# i - where - i = word2Int# ((b3 `uncheckedShiftL#` 24#) `or#` - (b2 `uncheckedShiftL#` 16#) `or#` - (b1 `uncheckedShiftL#` 8#) `or#` b0) - b3 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 3#))) - b2 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 2#))) - b1 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#))) - b0 = int2Word# (ord# (indexCharOffAddr# arr off')) - off' = off *# 4# -#else #if __GLASGOW_HASKELL__ >= 901 - GHC.Exts.int32ToInt# + GHC.Exts.int32ToInt# -- qualified import because it doesn't exist on older GHC's #endif - (indexInt32OffAddr# arr off) +#ifdef WORDS_BIGENDIAN + (GHC.Exts.word32ToInt32# (GHC.Exts.wordToWord32# (GHC.Exts.byteSwap32# (GHC.Exts.word32ToWord# (GHC.Exts.int32ToWord32# +#endif + (indexInt32OffAddr# arr off) +#ifdef WORDS_BIGENDIAN + ))))) #endif #else alexIndexInt32OffAddr = (Data.Array.!)