- BlackBox:
    name: GHC.Num.Integer.integerDiv
    kind: Declaration
    type: 'integerDiv :: Integer
      -> Integer -> Integer'
    template: |-
      // integerDiv begin
      logic ~GENSYM[resultPos][1];
      logic ~GENSYM[dividerNeg][2];
      logic signed [~SIZE[~TYPO]:0] ~GENSYM[dividend2][3];
      logic signed [~SIZE[~TYPO]:0] ~GENSYM[dividendE][4];
      logic signed [~SIZE[~TYPO]:0] ~GENSYM[dividerE][5];
      logic signed [~SIZE[~TYPO]:0] ~GENSYM[quot_res][6];

      assign ~SYM[1] = ~VAR[dividend][0][~SIZE[~TYPO]-1] == ~VAR[divider][1][~SIZE[~TYPO]-1];
      assign ~SYM[2] = ~VAR[divider][1][~SIZE[~TYPO]-1] == 1'b1;
      assign ~SYM[4] = $signed({{~VAR[dividend][0][~SIZE[~TYPO]-1]},~VAR[dividend][0]});  // sign extension
      assign ~SYM[5] = $signed({{~VAR[divider][1][~SIZE[~TYPO]-1]} ,~VAR[divider][1]} );  // sign extension

      assign ~SYM[3] = ~SYM[1] ? ~SYM[4]
                               : (~SYM[2] ? (~SYM[4] - ~SYM[5] - ~SIZE[~TYPO]'sd1)
                                          : (~SYM[4] - ~SYM[5] + ~SIZE[~TYPO]'sd1));

      assign ~SYM[6] = ~SYM[3] / ~SYM[5];
      assign ~RESULT = $signed(~SYM[6][~SIZE[~TYPO]-1:0]);
      // integerDiv end
    warning: 'GHC.Num.Integer.integerDiv: Integers are dynamically sized in simulation,
      but fixed-length after synthesis. Use carefully.'
- BlackBox:
    name: GHC.Num.Integer.integerMod
    kind: Declaration
    type: 'integerMod :: Integer
      -> Integer -> Integer'
    template: |-
      // integerMod begin
      // remainder
      ~SIGD[~GENSYM[rem_res][0]][0];
      assign ~SYM[0] = ~VAR[dividend][0] % ~VAR[divider][1];

      // modulo
      assign ~RESULT = (~VAR[dividend][0][~SIZE[~TYPO]-1] == ~VAR[divider][1][~SIZE[~TYPO]-1]) ?
                       ~SYM[0] :
                       ((~SYM[0] == ~SIZE[~TYPO]'sd0) ? ~SIZE[~TYPO]'sd0 : ~SYM[0] + ~VAR[divider][1]);
      // integerMod end
    warning: 'GHC.Num.Integer.integerMod: Integers are dynamically sized in simulation,
      but fixed-length after synthesis. Use carefully.'
- BlackBox:
    name: GHC.Num.Integer.integerDivMod#
    kind: Declaration
    type: 'integerDivMod ::
      Integer -> Integer -> (# Integer, Integer #)'
    template: |-
      // integerDivMod begin
      logic ~GENSYM[resultPos][1];
      logic ~GENSYM[dividerNeg][2];
      logic signed [~SIZE[~TYP[0]]:0] ~GENSYM[dividend2][3];
      logic signed [~SIZE[~TYP[0]]:0] ~GENSYM[dividendE][4];
      logic signed [~SIZE[~TYP[0]]:0] ~GENSYM[dividerE][5];
      logic signed [~SIZE[~TYP[0]]:0] ~GENSYM[quot_res][6];
      logic signed [~SIZE[~TYP[0]]-1:0] ~GENSYM[div_res][7];

      assign ~SYM[1] = ~VAR[dividend][0][~SIZE[~TYP[0]]-1] == ~VAR[divider][1][~SIZE[~TYP[0]]-1];
      assign ~SYM[2] = ~VAR[divider][1][~SIZE[~TYP[0]]-1] == 1'b1;
      assign ~SYM[4] = $signed({{~VAR[dividend][0][~SIZE[~TYP[0]]-1]},~VAR[dividend][0]});  // sign extension
      assign ~SYM[5] = $signed({{~VAR[divider][1][~SIZE[~TYP[0]]-1]} ,~VAR[divider][1]} );  // sign extension

      assign ~SYM[3] = ~SYM[1] ? ~SYM[4]
                               : (~SYM[2] ? (~SYM[4] - ~SYM[5] - ~SIZE[~TYP[0]]'sd1)
                                          : (~SYM[4] - ~SYM[5] + ~SIZE[~TYP[0]]'sd1));

      assign ~SYM[6] = ~SYM[3] / ~SYM[5];
      assign ~SYM[7] = $signed(~SYM[6][~SIZE[~TYP[0]]-1:0]);

      logic signed [~SIZE[~TYP[0]]-1:0] ~GENSYM[rem_res][8];
      logic signed [~SIZE[~TYP[0]]-1:0] ~GENSYM[mod_res][9];
      assign ~SYM[8] = ~VAR[dividend][0] % ~VAR[divider][1];
      assign ~SYM[9] = (~VAR[dividend][0][~SIZE[~TYP[0]]-1] == ~VAR[divider][1][~SIZE[~TYP[0]]-1]) ?
                       ~SYM[8] :
                       ((~SYM[8] == ~SIZE[~TYP[0]]'sd0) ? ~SIZE[~TYP[0]]'sd0 : ~SYM[8] + ~VAR[divider][1]);

      assign ~RESULT = {~SYM[7],~SYM[9]};
      // integerDivMod end
    warning: 'GHC.Num.Integer.integerDivMod#: Integers are dynamically sized in simulation,
      but fixed-length after synthesis. Use carefully.'
- BlackBox:
    name: GHC.Num.Integer.integerQuotRem#
    kind: Declaration
    type: 'integerQuotRem
      :: Integer -> Integer -> (# Integer, Integer #)'
    template: |-
      // integerQuotRem begin
      ~SIGD[~GENSYM[quot_res][0]][0];
      ~SIGD[~GENSYM[rem_res][1]][0];
      assign ~SYM[0] = ~ARG[0] / ~ARG[1];
      assign ~SYM[1] = ~ARG[0] % ~ARG[1];

      assign ~RESULT = {~SYM[0],~SYM[1]};
      // integerQuotRem end
    warning: 'GHC.Num.Integer.integerQuotRem#: Integers are dynamically sized in simulation,
      but fixed-length after synthesis. Use carefully.'
