open Op open PrepassSchedulingOracleDeps module FU74 = struct (* Attempt at modeling the FU74 (HiFive Unmatched board) core *) let resource_bounds = [| 2; 1; 1; 1; 1 |] (* issue ; LSU ; BU ; FPU ; IMUL/IDIV *) let nr_non_pipelined_units = 1 (* divider *) let latency_of_op (op : operation) (nargs : int) = match op with | OEmayundef _ -> 0 | Omove | Ointconst _ | Olongconst _ | Oaddrsymbol (_, _) | Oaddrstack _ | Ocast8signed | Ocast16signed | Oadd | Oaddimm _ | Oneg | Osub | Oand | Oandimm _ | Oor | Oorimm _ | Oxor | Oxorimm _ | Oshl | Oshlimm _ | Oshr | Oshrimm _ | Oshru | Oshruimm _ | Oshrximm _ | Olowlong | Ocast32signed | Ocast32unsigned | Oaddl | Oaddlimm _ | Onegl | Osubl | Oandl | Oandlimm _ | Oorl | Oorlimm _ | Oxorl | Oxorlimm _ | Oshll | Oshllimm _ | Oshrl | Oshrlimm _ | Oshrlu | Oshrluimm _ | Oshrxlimm _ | Oselectl | Obits_of_single | Obits_of_float | OEseqw _ | OEsnew _ | OEsequw _ | OEsneuw _ | OEsltw _ | OEsltuw _ | OEsltiw _ | OEsltiuw _ | OEaddiw (_, _) | OEandiw _ | OEoriw _ | OExoriw _ | OEluiw _ | OEseql _ | OEsnel _ | OEsequl _ | OEsneul _ | OEsltl _ | OEsltul _ | OEsltil _ | OEsltiul _ | OEaddil (_, _) | OEandil _ | OEoril _ | OExoril _ | OEluil _ | OEloadli _ -> 1 | Osingleconst _ | Ofloatconst _ | Onegf | Oabsf | Onegfs | Oabsfs | Osingleoffloat | Ofloatofsingle | Ofloatofint | Ofloatofintu | Osingleofint | Osingleofintu | Osingle_of_bits -> 2 | Omul | Omulhs | Omulhu | Omull | Omullhs | Omullhu -> 3 | Omulf -> 7 | Omulfs -> 5 | Ointoffloat | Ointuoffloat | Ointofsingle | Ointuofsingle | Olongoffloat | Olonguoffloat | Olongofsingle | Olonguofsingle | Osingleoflong | Osingleoflongu | OEfeqd | OEfltd | OEfled | OEfeqs | OEflts | OEfles -> 4 | Ofloatoflong | Ofloatoflongu | Ofloat_of_bits -> 6 | Oaddf | Osubf | Oaddfs | Osubfs -> 7 | Ocmp cond -> ( match cond with | Ccomp _ | Ccompu _ | Ccompimm _ | Ccompuimm _ | Ccompl _ | Ccomplu _ | Ccomplimm _ | Ccompluimm _ | CEbeqw _ | CEbnew _ | CEbequw _ | CEbneuw _ | CEbltw _ | CEbltuw _ | CEbgew _ | CEbgeuw _ | CEbeql _ | CEbnel _ | CEbequl _ | CEbneul _ | CEbltl _ | CEbltul _ | CEbgel _ | CEbgeul _ -> 1 | Ccompf _ | Cnotcompf _ | Ccompfs _ | Cnotcompfs _ -> 4) | Odiv | Odivu | Omod | Omodu | Odivl | Odivlu | Omodl | Omodlu | Odivf | Odivfs -> 68 | _ -> 1 let resources_of_op (op : operation) (nargs : int) = match op with | OEmayundef _ -> [| 0; 0; 0; 0; 0 |] | Omove | Ointconst _ | Olongconst _ | Oaddrsymbol (_, _) | Oaddrstack _ | Ocast8signed | Ocast16signed | Oadd | Oaddimm _ | Oneg | Osub | Oand | Oandimm _ | Oor | Oorimm _ | Oxor | Oxorimm _ | Oshl | Oshlimm _ | Oshr | Oshrimm _ | Oshru | Oshruimm _ | Oshrximm _ | Olowlong | Ocast32signed | Ocast32unsigned | Oaddl | Oaddlimm _ | Onegl | Osubl | Oandl | Oandlimm _ | Oorl | Oorlimm _ | Oxorl | Oxorlimm _ | Oshll | Oshllimm _ | Oshrl | Oshrlimm _ | Oshrlu | Oshrluimm _ | Oshrxlimm _ | Oselectl | Obits_of_single | Obits_of_float | OEseqw _ | OEsnew _ | OEsequw _ | OEsneuw _ | OEsltw _ | OEsltuw _ | OEsltiw _ | OEsltiuw _ | OEaddiw (_, _) | OEandiw _ | OEoriw _ | OExoriw _ | OEluiw _ | OEseql _ | OEsnel _ | OEsequl _ | OEsneul _ | OEsltl _ | OEsltul _ | OEsltil _ | OEsltiul _ | OEaddil (_, _) | OEandil _ | OEoril _ | OExoril _ | OEluil _ | OEloadli _ -> [| 1; 0; 0; 0; 0 |] | Omul | Omulhs | Omulhu | Omull | Omullhs | Omullhu | Odiv | Odivu | Omod | Omodu | Odivl | Odivlu | Omodl | Omodlu -> [| 1; 0; 0; 0; 1 |] | Omulf | Omulfs | Ointoffloat | Ointuoffloat | Ointofsingle | Ointuofsingle | Olongoffloat | Olonguoffloat | Olongofsingle | Olonguofsingle | Osingleoflong | Osingleoflongu | OEfeqd | OEfltd | OEfled | OEfeqs | OEflts | OEfles | Ofloatoflong | Ofloatoflongu | Ofloat_of_bits | Oaddf | Osubf | Oaddfs | Osubfs | Osingleconst _ | Ofloatconst _ | Onegf | Oabsf | Onegfs | Oabsfs | Osingleoffloat | Ofloatofsingle | Ofloatofint | Ofloatofintu | Osingleofint | Osingleofintu | Osingle_of_bits | Odivf | Odivfs -> [| 1; 0; 0; 1; 0 |] | Ocmp cond -> ( match cond with | Ccomp _ | Ccompu _ | Ccompimm _ | Ccompuimm _ | Ccompl _ | Ccomplu _ | Ccomplimm _ | Ccompluimm _ | CEbeqw _ | CEbnew _ | CEbequw _ | CEbneuw _ | CEbltw _ | CEbltuw _ | CEbgew _ | CEbgeuw _ | CEbeql _ | CEbnel _ | CEbequl _ | CEbneul _ | CEbltl _ | CEbltul _ | CEbgel _ | CEbgeul _ -> [| 1; 0; 0; 0; 0 |] | Ccompf _ | Cnotcompf _ | Ccompfs _ | Cnotcompfs _ -> [| 1; 0; 0; 1; 0 |]) | _ -> [| 1; 0; 0; 0; 0 |] let non_pipelined_resources_of_op (op : operation) (nargs : int) = match op with | Odiv | Odivu | Odivl | Odivlu | Odivf | Odivfs -> [| 68 |] | _ -> [| -1 |] let resources_of_cond (cond : condition) (nargs : int) = match cond with | Ccompf _ | Cnotcompf _ | Ccompfs _ | Cnotcompfs _ -> [| 1; 0; 1; 1; 0 |] | _ -> [| 1; 0; 1; 0; 0 |] let latency_of_load trap chunk (addr : addressing) (nargs : int) = 3 let latency_of_call _ _ = 6 let resources_of_load trap chunk addressing nargs = [| 1; 1; 0; 0; 0 |] let resources_of_store chunk addressing nargs = [| 1; 1; 0; 0; 0 |] let resources_of_call _ _ = resource_bounds let resources_of_builtin _ = resource_bounds end module Rocket = struct (* Attempt at modeling the Rocket core *) let resource_bounds = [| 1 |] let nr_non_pipelined_units = 1 (* divider *) let latency_of_op (op : operation) (nargs : int) = match op with | Omul | Omulhs | Omulhu | Omull | Omullhs | Omullhu -> 4 | Onegf -> 1 (*r [rd = - r1] *) | Oabsf (*r [rd = abs(r1)] *) | Oaddf (*r [rd = r1 + r2] *) | Osubf (*r [rd = r1 - r2] *) | Omulf -> 6 (*r [rd = r1 * r2] *) | Onegfs -> 1 (*r [rd = - r1] *) | Oabsfs (*r [rd = abs(r1)] *) | Oaddfs (*r [rd = r1 + r2] *) | Osubfs (*r [rd = r1 - r2] *) | Omulfs -> 4 (*r [rd = r1 * r2] *) | Osingleoffloat (*r [rd] is [r1] truncated to single-precision float *) | Ofloatofsingle (*r [rd] is [r1] extended to double-precision float *) (*c Conversions between int and float: *) | Ofloatconst _ | Osingleconst _ | Ointoffloat (*r [rd = signed_int_of_float64(r1)] *) | Ointuoffloat (*r [rd = unsigned_int_of_float64(r1)] *) | Ofloatofint (*r [rd = float64_of_signed_int(r1)] *) | Ofloatofintu (*r [rd = float64_of_unsigned_int(r1)] *) | Ointofsingle (*r [rd = signed_int_of_float32(r1)] *) | Ointuofsingle (*r [rd = unsigned_int_of_float32(r1)] *) | Osingleofint (*r [rd = float32_of_signed_int(r1)] *) | Osingleofintu (*r [rd = float32_of_unsigned_int(r1)] *) | Olongoffloat (*r [rd = signed_long_of_float64(r1)] *) | Olonguoffloat (*r [rd = unsigned_long_of_float64(r1)] *) | Ofloatoflong (*r [rd = float64_of_signed_long(r1)] *) | Ofloatoflongu (*r [rd = float64_of_unsigned_long(r1)] *) | Olongofsingle (*r [rd = signed_long_of_float32(r1)] *) | Olonguofsingle (*r [rd = unsigned_long_of_float32(r1)] *) | Osingleoflong (*r [rd = float32_of_signed_long(r1)] *) | Osingleoflongu -> 2 (*r [rd = float32_of_unsigned_int(r1)] *) | OEfeqd | OEfltd | OEfeqs | OEflts | OEfles | OEfled | Obits_of_single | Obits_of_float | Osingle_of_bits | Ofloat_of_bits -> 2 | OEloadli _ -> 2 | Odiv | Odivu | Odivl | Odivlu -> 16 | Odivfs -> 35 | Odivf -> 50 | Ocmp cond -> ( match cond with | Ccomp _ | Ccompu _ | Ccompimm _ | Ccompuimm _ | Ccompl _ | Ccomplu _ | Ccomplimm _ | Ccompluimm _ | CEbeqw _ | CEbnew _ | CEbequw _ | CEbneuw _ | CEbltw _ | CEbltuw _ | CEbgew _ | CEbgeuw _ | CEbeql _ | CEbnel _ | CEbequl _ | CEbneul _ | CEbltl _ | CEbltul _ | CEbgel _ | CEbgeul _ -> 1 | Ccompf _ | Cnotcompf _ -> 2 | Ccompfs _ | Cnotcompfs _ -> 2) | OEmayundef _ -> 0 | _ -> 1 let resources_of_op (op : operation) (nargs : int) = match op with OEmayundef _ -> [| 0 |] | _ -> resource_bounds let non_pipelined_resources_of_op (op : operation) (nargs : int) = match op with | Odiv | Odivu -> [| 29 |] | Odivfs -> [| 20 |] | Odivl | Odivlu | Odivf -> [| 50 |] | _ -> [| -1 |] let resources_of_cond (cond : condition) (nargs : int) = resource_bounds let latency_of_load trap chunk (addr : addressing) (nargs : int) = 3 let latency_of_call _ _ = 6 let resources_of_load trap chunk addressing nargs = resource_bounds let resources_of_store chunk addressing nargs = resource_bounds let resources_of_call _ _ = resource_bounds let resources_of_builtin _ = resource_bounds end module SweRV_EH1 = struct (* Attempt at modeling SweRV EH1 [| issues ; LSU ; multiplier |] *) let resource_bounds = [| 2; 1; 1 |] let nr_non_pipelined_units = 1 (* divider *) let latency_of_op (op : operation) (nargs : int) = match op with | Omul | Omulhs | Omulhu | Omull | Omullhs | Omullhu -> 3 | Odiv | Odivu | Odivl | Odivlu -> 16 | _ -> 1 let resources_of_op (op : operation) (nargs : int) = match op with | Omul | Omulhs | Omulhu | Omull | Omullhs | Omullhu -> [| 1; 0; 1 |] | Odiv | Odivu | Odivl | Odivlu -> [| 0; 0; 0 |] | _ -> [| 1; 0; 0 |] let non_pipelined_resources_of_op (op : operation) (nargs : int) = match op with | Odiv | Odivu -> [| 29 |] | Odivfs -> [| 20 |] | Odivl | Odivlu | Odivf -> [| 50 |] | _ -> [| -1 |] let resources_of_cond (cond : condition) (nargs : int) = [| 1; 0; 0 |] let latency_of_load trap chunk (addr : addressing) (nargs : int) = 3 let latency_of_call _ _ = 6 let resources_of_load trap chunk addressing nargs = [| 1; 1; 0 |] let resources_of_store chunk addressing nargs = [| 1; 1; 0 |] let resources_of_call _ _ = resource_bounds let resources_of_builtin _ = resource_bounds end let get_opweights () : opweights = match !Clflags.option_mtune with | "rocket" | "" -> { pipelined_resource_bounds = Rocket.resource_bounds; nr_non_pipelined_units = Rocket.nr_non_pipelined_units; latency_of_op = Rocket.latency_of_op; resources_of_op = Rocket.resources_of_op; non_pipelined_resources_of_op = Rocket.non_pipelined_resources_of_op; latency_of_load = Rocket.latency_of_load; resources_of_load = Rocket.resources_of_load; resources_of_store = Rocket.resources_of_store; resources_of_cond = Rocket.resources_of_cond; latency_of_call = Rocket.latency_of_call; resources_of_call = Rocket.resources_of_call; resources_of_builtin = Rocket.resources_of_builtin; } | "SweRV_EH1" | "EH1" -> { pipelined_resource_bounds = SweRV_EH1.resource_bounds; nr_non_pipelined_units = SweRV_EH1.nr_non_pipelined_units; latency_of_op = SweRV_EH1.latency_of_op; resources_of_op = SweRV_EH1.resources_of_op; non_pipelined_resources_of_op = SweRV_EH1.non_pipelined_resources_of_op; latency_of_load = SweRV_EH1.latency_of_load; resources_of_load = SweRV_EH1.resources_of_load; resources_of_store = SweRV_EH1.resources_of_store; resources_of_cond = SweRV_EH1.resources_of_cond; latency_of_call = SweRV_EH1.latency_of_call; resources_of_call = SweRV_EH1.resources_of_call; resources_of_builtin = SweRV_EH1.resources_of_builtin; } | "FU74" | "sifive-u74" -> { pipelined_resource_bounds = FU74.resource_bounds; nr_non_pipelined_units = FU74.nr_non_pipelined_units; latency_of_op = FU74.latency_of_op; resources_of_op = FU74.resources_of_op; non_pipelined_resources_of_op = FU74.non_pipelined_resources_of_op; latency_of_load = FU74.latency_of_load; resources_of_load = FU74.resources_of_load; resources_of_store = FU74.resources_of_store; resources_of_cond = FU74.resources_of_cond; latency_of_call = FU74.latency_of_call; resources_of_call = FU74.resources_of_call; resources_of_builtin = FU74.resources_of_builtin; } | xxx -> failwith (Printf.sprintf "unknown -mtune: %s" xxx)