codegen.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. init_codegen
  2. gen_verb
  3. gen_make_frame
  4. gen_exp
  5. gen_add_grp
  6. gen_cmp_grp
  7. gen_label
  8. gen_goto
  9. gen_jz
  10. gen_set

   1 /*
   2 
   3 Tiny ZiNC Compiler --- code generater
   4 
   5 
   6 Copyright (C) 2000  KISHIMOTO, Makoto
   7 
   8 This program is free software; you can redistribute it and/or modify
   9 it under the terms of the GNU General Public License as published by
  10 the Free Software Foundation; either version 2 of the License, or
  11 (at your option) any later version.
  12 
  13 This program is distributed in the hope that it will be useful,
  14 but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 GNU General Public License for more details.
  17 
  18 You should have received a copy of the GNU General Public License
  19 along with this program; if not, write to the Free Software
  20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21 
  22 
  23         KISHIMOTO, Makoto <cs96068@cs.tuat.ac.jp>
  24 
  25 */
  26 
  27 /*
  28 
  29         コードジェネレータ
  30 
  31 */
  32 
  33 #include <stddef.h>
  34 #include <stdlib.h>
  35 #include <stdio.h>
  36 
  37 #include "confdef.h"
  38 
  39 #include "express.h"
  40 #include "name.h"
  41 #include "labelgen.h"
  42 
  43 #include "codegen.h"
  44 
  45 static void gen_add_grp(exp_node *p, char const op[]);
  46 static void gen_cmp_grp(exp_node *p, char const op[]);
  47 
  48 static FILE *out_file;
  49 
  50 void
  51 init_codegen(FILE *fp)
     /* [<][>][^][v][top][bottom][index][help] */
  52 {
  53   out_file = fp;
  54 }
  55 
  56 void
  57 gen_verb(char s[])
     /* [<][>][^][v][top][bottom][index][help] */
  58 {
  59   fprintf(out_file, "%s", s);
  60 }
  61 
  62 void
  63 gen_make_frame(int size)
     /* [<][>][^][v][top][bottom][index][help] */
  64 {
  65   fprintf(out_file, "\tsubl $%d, %%esp\n", size);
  66 }
  67 
  68 void
  69 gen_exp(exp_node *p)
     /* [<][>][^][v][top][bottom][index][help] */
  70 {
  71   switch (p->type)
  72     {
  73     case EXP_ISEQ:
  74       gen_cmp_grp(p, "jne");  /* 条件の反転に注意 */
  75       break;
  76     case EXP_ISNOTEQ:
  77       gen_cmp_grp(p, "je");  /* 条件の反転に注意 */
  78       break;
  79     case EXP_ISLT:
  80       gen_cmp_grp(p, "jnl");  /* 条件の反転に注意 */
  81       break;
  82     case EXP_ISGT:
  83       gen_cmp_grp(p, "jng");  /* 条件の反転に注意 */
  84       break;
  85     case EXP_ISLTEQ:
  86       gen_cmp_grp(p, "jnle");  /* 条件の反転に注意 */
  87       break;
  88     case EXP_ISGTEQ:
  89       gen_cmp_grp(p, "jnge");  /* 条件の反転に注意 */
  90       break;
  91 
  92     case EXP_ADD:
  93       gen_add_grp(p, "addl");
  94       break;
  95     case EXP_SUB:
  96       gen_add_grp(p, "subl");
  97       break;
  98     case EXP_OR:
  99       gen_add_grp(p, "orl");
 100       break;
 101 
 102     case EXP_MUL:
 103       gen_exp(p->val._2._1);
 104       fprintf(out_file, "\tpushl %%eax\n");
 105       gen_exp(p->val._2._0);
 106       fprintf(out_file, "\tpopl %%ecx\n");
 107       fprintf(out_file, "\timull %%ecx, %%eax\n");
 108       break;
 109     case EXP_DIV:
 110       gen_exp(p->val._2._1);
 111       fprintf(out_file, "\tpushl %%eax\n");
 112       gen_exp(p->val._2._0);
 113       fprintf(out_file, "\tpopl %%ecx\n");
 114       fprintf(out_file, "\tcltd\n");
 115       fprintf(out_file, "\tidivl %%ecx, %%eax\n");
 116       break;
 117     case EXP_MOD:
 118       gen_exp(p->val._2._1);
 119       fprintf(out_file, "\tpushl %%eax\n");
 120       gen_exp(p->val._2._0);
 121       fprintf(out_file, "\tpopl %%ecx\n");
 122       fprintf(out_file, "\tcltd\n");
 123       fprintf(out_file, "\tidivl %%ecx, %%eax\n");
 124       fprintf(out_file, "\tmovl %%edx, %%eax\n");
 125       break;
 126     case EXP_LSL:
 127       gen_exp(p->val._2._1);
 128       fprintf(out_file, "\tpushl %%eax\n");
 129       gen_exp(p->val._2._0);
 130       fprintf(out_file, "\tpopl %%ecx\n");
 131       fprintf(out_file, "\tshll %%cl, %%eax\n");
 132       break;
 133     case EXP_ASR:
 134       gen_exp(p->val._2._1);
 135       fprintf(out_file, "\tpushl %%eax\n");
 136       gen_exp(p->val._2._0);
 137       fprintf(out_file, "\tpopl %%ecx\n");
 138       fprintf(out_file, "\tsarl %%cl, %%eax\n");
 139       break;
 140     case EXP_LSR:
 141       gen_exp(p->val._2._1);
 142       fprintf(out_file, "\tpushl %%eax\n");
 143       gen_exp(p->val._2._0);
 144       fprintf(out_file, "\tpopl %%ecx\n");
 145       fprintf(out_file, "\tshrl %%cl, %%eax\n");
 146       break;
 147 
 148     case EXP_AND:
 149       gen_add_grp(p, "andl");
 150       break;
 151     case EXP_NOT:
 152       gen_exp(p->val._1._0);
 153       fprintf(out_file, "\tnotl %%eax\n");
 154       break;
 155     case EXP_PLUS:
 156       gen_exp(p->val._1._0);
 157       break;
 158     case EXP_MINUS:
 159       gen_exp(p->val._1._0);
 160       fprintf(out_file, "\tnegl %%eax\n");
 161       break;
 162 
 163     case EXP_CONST:
 164       fprintf(out_file, "\tmovl $%d, %%eax\n", p->val.constval);
 165       break;
 166     case EXP_VAR:
 167       {
 168         name_type var_scope;
 169         var_scope = name_get_type(p->val.var);
 170         if (var_scope == NAME_GLO_VAR)
 171           {
 172             fprintf(out_file, "\tmovl %s, %%eax\n", name_get_str(p->val.var));
 173           }
 174         else if (var_scope == NAME_LOC_VAR)
 175           {
 176             fprintf(out_file, "\tmovl -%d(%%ebp), %%eax\n", name_get_id(p->val.var));
 177           }
 178         else
 179           {
 180             EMSTOP("internal conflict", 0);
 181             exit(1);
 182           }
 183         break;
 184       }
 185     }
 186 }
 187 
 188 static void
 189 gen_add_grp(exp_node *p, char const op[])
     /* [<][>][^][v][top][bottom][index][help] */
 190 {
 191   gen_exp(p->val._2._1);
 192   fprintf(out_file, "\tpushl %%eax\n");
 193   gen_exp(p->val._2._0);
 194   fprintf(out_file, "\tpopl %%ecx\n");
 195   fprintf(out_file, "\t%s %%ecx, %%eax\n", op);
 196 }
 197 
 198 static void
 199 gen_cmp_grp(exp_node *p, char const op[])
     /* [<][>][^][v][top][bottom][index][help] */
 200 {
 201   int label;
 202 
 203   gen_add_grp(p, "cmpl");
 204   fprintf(out_file, "\tmovl $0, %%eax\n");  /* 注 : ←ここを xorl %eax, %eax に */
 205   label = getnewnum();                      /*      しては **いけない** */
 206   fprintf(out_file, "\t%s L.%d\n", op, label);  /* なぜなら←ここで見ている */
 207   fprintf(out_file, "\tnotl %%eax\n");  /* フラグを破壊してしまうからである */
 208   gen_label(label);
 209 }
 210 
 211 void
 212 gen_label(int n)
     /* [<][>][^][v][top][bottom][index][help] */
 213 {
 214   fprintf(out_file, "L.%d:\n", n);
 215 }
 216 
 217 void
 218 gen_goto(int n)
     /* [<][>][^][v][top][bottom][index][help] */
 219 {
 220   fprintf(out_file, "\tjmp L.%d\n", n);
 221 }
 222 
 223 void
 224 gen_jz(int n)
     /* [<][>][^][v][top][bottom][index][help] */
 225 {
 226   fprintf(out_file, "\tjz L.%d\n", n);
 227 }
 228 
 229 void
 230 gen_set(name_info *store_to)
     /* [<][>][^][v][top][bottom][index][help] */
 231 {
 232   name_type var_scope;
 233 
 234   var_scope = name_get_type(store_to);
 235   if (var_scope == NAME_GLO_VAR)
 236     {
 237       fprintf(out_file, "\tmovl %%eax, %s\n", name_get_str(store_to));
 238     }
 239   else if (var_scope == NAME_LOC_VAR)
 240     {
 241       fprintf(out_file, "\tmovl %%eax, -%d(%%ebp)\n", name_get_id(store_to));
 242     }
 243   else
 244     {
 245       EMSTOP("internal conflict", 0);
 246       exit(1);
 247     }
 248 }

/* [<][>][^][v][top][bottom][index][help] */