module LinearScan.ScanState where


import Debug.Trace (trace, traceShow)
import qualified Prelude
import qualified Data.IntMap
import qualified Data.IntSet
import qualified Data.List
import qualified Data.Ord
import qualified Data.Functor.Identity
import qualified LinearScan.Utils

import qualified LinearScan.Interval as Interval
import qualified LinearScan.List1 as List1
import qualified LinearScan.Prelude0 as Prelude0
import qualified LinearScan.Seq as Seq


type PhysReg = Prelude.Int

type FixedIntervalsType = [] (Prelude.Maybe Interval.IntervalDesc)

data ScanStateDesc =
   Build_ScanStateDesc Prelude.Int ([] Interval.IntervalDesc) FixedIntervalsType 
 ([] ((,) Prelude.Int Prelude.Int)) ([] ((,) Prelude.Int PhysReg)) ([]
                                                                   ((,)
                                                                   Prelude.Int
                                                                   PhysReg)) 
 ([] ((,) Prelude.Int (Prelude.Maybe PhysReg)))

nextInterval :: Prelude.Int -> ScanStateDesc -> Prelude.Int
nextInterval maxReg s =
  case s of {
   Build_ScanStateDesc nextInterval0 intervals0 fixedIntervals0 unhandled0
    active0 inactive0 handled0 -> nextInterval0}

type IntervalId = Prelude.Int

intervals :: Prelude.Int -> ScanStateDesc -> [] Interval.IntervalDesc
intervals maxReg s =
  case s of {
   Build_ScanStateDesc nextInterval0 intervals0 fixedIntervals0 unhandled0
    active0 inactive0 handled0 -> intervals0}

fixedIntervals :: Prelude.Int -> ScanStateDesc -> FixedIntervalsType
fixedIntervals maxReg s =
  case s of {
   Build_ScanStateDesc nextInterval0 intervals0 fixedIntervals0 unhandled0
    active0 inactive0 handled0 -> fixedIntervals0}

unhandled :: Prelude.Int -> ScanStateDesc -> [] ((,) IntervalId Prelude.Int)
unhandled maxReg s =
  case s of {
   Build_ScanStateDesc nextInterval0 intervals0 fixedIntervals0 unhandled0
    active0 inactive0 handled0 -> unhandled0}

active :: Prelude.Int -> ScanStateDesc -> [] ((,) IntervalId PhysReg)
active maxReg s =
  case s of {
   Build_ScanStateDesc nextInterval0 intervals0 fixedIntervals0 unhandled0
    active0 inactive0 handled0 -> active0}

inactive :: Prelude.Int -> ScanStateDesc -> [] ((,) IntervalId PhysReg)
inactive maxReg s =
  case s of {
   Build_ScanStateDesc nextInterval0 intervals0 fixedIntervals0 unhandled0
    active0 inactive0 handled0 -> inactive0}

handled :: Prelude.Int -> ScanStateDesc -> []
           ((,) IntervalId (Prelude.Maybe PhysReg))
handled maxReg s =
  case s of {
   Build_ScanStateDesc nextInterval0 intervals0 fixedIntervals0 unhandled0
    active0 inactive0 handled0 -> handled0}

sortRegisterVector :: Prelude.Int -> ([] Prelude.Bool) -> ([]
                      (Prelude.Maybe Prelude0.Coq_oddnum)) -> []
                      ((,) PhysReg (Prelude.Maybe Prelude0.Coq_oddnum))
sortRegisterVector maxReg fixedAndIntersects =
  (LinearScan.Utils.vfoldl'_with_index) maxReg (\reg acc mpos ->
    let {
     f = \x y ->
      case x of {
       (,) xreg xmpos ->
        case y of {
         (,) yreg ympos ->
          let {xfi = LinearScan.Utils.nth maxReg fixedAndIntersects xreg} in
          let {yfi = LinearScan.Utils.nth maxReg fixedAndIntersects yreg} in
          case (Prelude.&&) xfi (Prelude.not yfi) of {
           Prelude.True -> Prelude.False;
           Prelude.False ->
            case xmpos of {
             Prelude.Just xn ->
              case ympos of {
               Prelude.Just yn -> (Prelude.<=) ((Prelude.succ) ( yn)) ( xn);
               Prelude.Nothing -> Prelude.False};
             Prelude.Nothing -> Prelude.True}}}}}
    in
    List1.insert f ((,) reg mpos) acc) []

registerWithHighestPos :: Prelude.Int -> ([] Prelude.Bool) -> ([]
                          (Prelude.Maybe Prelude0.Coq_oddnum)) -> (,) 
                          PhysReg (Prelude.Maybe Prelude0.Coq_oddnum)
registerWithHighestPos maxReg fixedAndIntersects =
  (Prelude..) (Seq.head ((,) ( 0) (Prelude.Just Prelude0.odd1)))
    (sortRegisterVector maxReg fixedAndIntersects)

data ScanStateStatus =
   Pending
 | InUse

type ScanStateSig = ScanStateDesc

packScanState :: Prelude.Int -> ScanStateStatus -> ScanStateDesc ->
                 ScanStateDesc
packScanState maxReg b sd =
  sd