CS-536 Class Notes April 29, 1998 
Charles Fisher 
Discussion 

Covers: Code Generation of If-Then-Else statements, nested If's  and the Translation of operators, complex Statements, Unary Ops and Type Casting. 
Misc: 
   Handed out Part III of Code Generation.     Mistakes in Handouts 
  • Page 5 of the CSX Code Generation Routines Part II. Two cases sym.LEQ one needs to be changed to case sym.GTEQ and then return "ge".  (The master copy from above has been changed)
  • Page 6 of the CSX Code Generation Routines Part III. One of the operand.type.val == Types.Integer has to be changed to operand.type.val == Types.Character.

If Statements: 
     IF STMT  //Evaluate Boolean Expression 
   To Do 
  • Evaluate the control expression and put it on top of stack.
  • Perform conditional jumps. (Below is the assembly code form)
                IFEQ L1                 {Code for false condition generated here} 
                    GOTO L2    //Exit Point, Executed the THEN and is leaving block. 
                L1: 
                 {Code for to execute when the  IF Stmt true} 
                L2: 


Code Generation of  IF-THEN   
    The Code: 
           CG () { 
               condition.cg();                       //  Generates the code to determine if true or false and puts it 
                                                                   on Stack 
               String elseLab = genLab ();  // This never gets used in CSX Lite, becuase no else stmts. 
               if (! elsePart.isNull()) {       //  Do not need to branch if there is no else part. 
                   branchZ (elseLab);} 
               ThenPart.cg();                       // Generates code to do in the then part. 
               String endLab = genLab();   // Gets a new label for the end of IF-THEN 
               branch (endLab); 
               if (! elsePart.isNull()) {       //  Do not need to generate code if there is no else part. 
                   elsePart.cg();}                  //  Generate code for else part. 
               defineLab(endLab); 
            } 
 
     Question: What happens with if-then without an else? 
         answer: The else part is Null so its acceptable to ask a Null Node to generate Nothing 

      Question: Do nested if statments work?  
          answer:  Yes 
            example: 
               if (b1){ 
                 if (b2) {a=0;} 
                 else {a=1;} 
               else {a=2;] 

       Solution: Walk through the Algorithm to show it works of code Generation. 
             GetStatic c/b1 $ I 
             IFEQ L1                     //if(b1) 
             GetStatic c/b2 $ I 
             IFEQ L2                     //if(b2) 
             LDC 0                        // a=0, gets put on stack 
             PutStatic c/a $ I 
             Goto L3                     //Has the indirect effect of getting out of enclosing if Statment 
        L2: 
             LDC 1 
             PutStatic c/a$ I          // a=1 
        L3: 
             GOTO L4 
        L1: 
              LDC 2 
              PutStatic c/a$ I          // a=2
        L4: 
       //This is the code generated and it does handle the nested if's. 
 
    Question: Is there a problem here? 
         answer: A small one.  We have Jump Chaining which is a jump to a jump.  Some compilers 
                       will optimize this, but it is not required. 
  
    Another issue of translating operators 

  • Do not leave value on stack but use conditon Branch
  • Relational Operators

Relational Opeators 
     IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, 
        For example: 
          if(a<b) {                    //This is handled by code for genRelationalOp on page 5 of Part II 
             z=0;} 
          else {} 
        
      This is a specialized if statment. 
           So what we need to do to anaylize we need to push the values of 'a' and 'b' on to the stack.   
           Then we can use: 
              IF_ICMPLT  True    // This takes the top two values on the stack and branchs if Less than. 
              LDC 0                       // If it is not true it is False so put 0 on Stack. 
              GOTO Skip 
          True: 
              LDC 1                      // The expression is true so put 1 on stack. 
           Skip: 
        // This code generated by genRelationalOp() on Page 5 of Part II 
        // Then we need to add on the if part since we have the value we want is on stack 
              IFEQ Else 
              LDC 0 
              putStatic c/z$ I 
           Else: 
        // That part takes care of the if 

       Question: What happens in context of if-then with complex statments 
           answer: The trick is to do it right once and it will always work. 
           example: if ((a<b)&&(c>d)) 
           If we follow the algorithms we can generate the code: 
              push a 
              push b 
              IF_ICMPLT  True    // This takes the top two values on the stack and branchs if Less than. 
              LDC 0                       // If it is not true it is False so put 0 on Stack. 
              GOTO Skip 
          True: 
              LDC 1                      // The expression is true so put 1 on stack. 
           Skip:                            // at this point the value of a<b is on stack. 
              push c 
              push d 
              IF_ICMPGT  True2  // We just repeat what we did for a>b except use Greter than 
              LDC 0                       // If it is not true it is False so put 0 on Stack. 
              GOTO Skip2 
          True2: 
              LDC 1                      // The expression is true so put 1 on stack. 
           Skip2: 
              IAND                       //Whola, it compares 2 top values and puts the result on the stack. 
         //Then the if code gets generated. 
              IFEQ Else 
              LDC 0 
              putStatic c/z$ I 
           Else: 
        // That part takes care of the if 

      Question: Will pop ever get used? 
         answer: You will not have to use a pop at all.  Commands will pop everything off. 


Type Casting 
   Is just part of the if-Then code again.
     What we will do is consider the only types we can type cast are Bool, Int, Char and look at the 
      9 possiblites we have to account for.

                                                                          Type of Operand

Integer Character Boolean
to Integer Do nothing same type Character is represented as a init. Do Nothing Boolean is already a 1 or zero. Do nothing.
to Character Have to generate.  See code below. Do nothing same type Do Nothing, 
to Boolean Have to generate.  See code below Have to generate. See code below Do nothing same type

     Code for (Bool) Int and (Bool) Char
       if (operand != 0) {push 1}      //if the value is not 0 then it is a true stament so push true
        else {push 0}                          //if the value is 0 then the statement is false. 
      //again this is just the if statment and it will generate the same code.

     Code fir (Char) Int
       Here we just have to mask out 111111B.  We use IAND to do that.
            push int   //push the int onto the stack
            ldc 127   //pushes the mask on stack
            IAND     //leaves the Casted value on top of stack



Unary Operator (not)
    You do not want to use a compliment for Not you want to use xor.
         A true boolean = 000000..001 and a false = 00000..000 so the compliment would be wrong 
         because it would make true = 11111..110 which is not 0.  So what you wnat to do is us XOR
         with 000...001.
            push bool   //push the bool onto the stack
            ldc 1   //pushes the mask on stack
            XOR  //will leave the real value on stack.
 



David Toal