[M3devel] NT386 div/mod

Jay K jay.krell at cornell.edu
Fri Jan 22 12:55:29 CET 2010


It is interesting to note that NT386 doesn't use the m3_mod/div functions, but generates inline code:

 

PROCEDURE diffdivOp (t: T; READONLY divisor: Operand; apos: BOOLEAN) =
  VAR
    diffsignlab := reserve_labels(t, 1, TRUE);
    endlab := reserve_labels(t, 1, TRUE);
  BEGIN
    <* ASSERT divisor.loc = OLoc.register *>
    movOp(t, t.reg[EDX], t.reg[EAX]);                 (*   MOV EDX, EAX      *)
    binOp(t, Op.oXOR, t.reg[EDX], divisor);           (*   XOR EDX, divisor  *)
    brOp(t, Cond.L, diffsignlab);                     (*   JL  diffsignlab   *)
    IF apos
      THEN binOp(t, Op.oXOR, t.reg[EDX], t.reg[EDX]); (*   XOR EDX, EDX      *)
      ELSE noargOp(t, Op.oCDQ);                       (*   CDQ               *)
    END;
    idivOp(t, divisor);                               (*   IDIV EAX, divisor *)
    brOp(t, Cond.Always, endlab);                     (*   JMP endlab        *)
    set_label(t, diffsignlab);                        (* .diffsignlab        *)
    noargOp(t, Op.oCDQ);                              (*   CDQ               *)
    idivOp(t, divisor);                               (*   IDIV EAX, divisor *)
    immOp(t, Op.oCMP, t.reg[EDX], TZero);             (*   CMP EDX, #0       *)
    brOp(t, Cond.E, endlab);                          (*   JE  endlab        *)
    decOp(t, t.reg[EAX]);                             (*   DEC EAX           *)
    set_label(t, endlab);                             (* .endlab             *)
  END diffdivOp;

 

PROCEDURE diffmodOp (t: T; READONLY divisor: Operand; apos: BOOLEAN) =
  VAR
    diffsignlab := reserve_labels(t, 1, TRUE);
    endlab := reserve_labels(t, 1, TRUE);
  BEGIN
    <* ASSERT divisor.loc = OLoc.register *>

    movOp(t, t.reg[EDX], t.reg[EAX]);                 (*    MOV EDX, EAX      *)
    binOp(t, Op.oXOR, t.reg[EDX], divisor);           (*    XOR EDX, divisor  *)
    brOp(t, Cond.L, diffsignlab);                     (*    JL  diffsignlab   *)
    IF apos
      THEN binOp(t, Op.oXOR, t.reg[EDX], t.reg[EDX]); (*    XOR EDX, EDX      *)
      ELSE noargOp(t, Op.oCDQ);                       (*    CDQ               *)
    END;
    idivOp(t, divisor);                               (*    IDIV EAX, divisor *)
    brOp(t, Cond.Always, endlab);                     (*    JMP endlab        *)
    set_label(t, diffsignlab);                        (* .diffsignlab         *)
    noargOp(t, Op.oCDQ);                              (*    CDQ               *)
    idivOp(t, divisor);                               (*    IDIV EAX, divisor *)
    immOp(t, Op.oCMP, t.reg[EDX], TZero);             (*    CMP EDX, #0       *)
    brOp(t, Cond.E, endlab);                          (*    JE  endlab        *)
    binOp(t, Op.oADD, t.reg[EDX], divisor);           (*    ADD EDX, divisor  *)
    set_label(t, endlab);                             (* .endlab              *)
  END diffmodOp;


 

I haven't tested it yet, but of course you can see that same signed inputs are simpler, like with the code in hand.c.

I'm really starting to like CARDINAL and not INTEGER. :)

(Plus the subtlety that CARDINAL has a default initialization to 0 that Tony told me about.)

 

 

 - Jay
 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20100122/5bf37fec/attachment-0001.html>


More information about the M3devel mailing list