mipsy-builder-gen.py 3.96 KB
Newer Older
1
#!/usr/bin/env python
Benoit Perrot's avatar
Benoit Perrot committed
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
##
## This file is part of Mipsy, a tiny MIPS simulator
## Copyright (C) 2003 Benoit Perrot <benoit@lrde.epita.fr>
##
## Mipsy is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
## 
## Mipsy is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
## 
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##
20
21
22
23
24

import sys
import string, re

import mipsy
Benoit Perrot's avatar
Benoit Perrot committed
25
from mipsy import license, depth, class_id
26
27
28
29
30
31
32
33
34
35
36
37
38

parser = mipsy.InstructionSetParser()
instructions = parser.parse(sys.stdin)

#### Mipsy Program builder generator -----------------------

print license
print """#ifndef INST_PROGRAM_BUILDER_HH
# define INST_PROGRAM_BUILDER_HH

# include \"inst/all.hh\"
# include \"inst/program.hh\"

39
40
# include \"vm/cpu.hh\"

41
42
43
44
namespace inst
{

  using namespace inst;
45
  using vm::Cpu;
46
47
48
49
  
  class ProgramBuilder
  {
  public:
50
51
    ProgramBuilder(bool fill_delay_slot_p = false):
      _program(0), fill_delay_slot_p(fill_delay_slot_p)
52
53
54
55
    {
    }

  public:
56
    void		reset(bool fill_delay_slot_p = false)
57
    {
58
      this->fill_delay_slot_p = fill_delay_slot_p;
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
      _program = new Program();
    }
    
    Program*		get()
    {
      return _program;
    }
    
  public:
    void		add_data_label(Label& label)
    {
      _program->data_section ().add_label(label);
    }
    void		add_inst_label(Label& label)
    {
      _program->text_section ().add_label(label);
    }

    void                add_space (int size)
    {
      _program->data_section ().add_space(size);    
    }

    void		add_word (int imm)
    {
      _program->data_section ().add_word (imm);
    }
    void		add_word (Label& label)
    {
      _program->data_section ().
        add_word (_program->data_section ().get_offset(label));
    }

    void		add_asciiz (const std::string& str)
    {
      _program->data_section ().add_asciiz (str);
    }

  public:"""

type_map = {
    "register": "Register&",
    "immediate": "Exp&",
102
    "label": "Exp&",
103
104
105
106
    "address": "Register&"
    }

for inst in instructions:
Benoit Perrot's avatar
Benoit Perrot committed
107
108
109
  for syntax in inst.syntaxes:
    if (syntax.alias != "") or (syntax.level == "pseudo"):
      continue
110
    
Benoit Perrot's avatar
Benoit Perrot committed
111
112
113
114
115
116
117
118
119
120
121
122
123
    if syntax.level == "native":
      proto = ""
      call = ""
      for attribute in inst.format.params:
        proto = proto + type_map[attribute.kind] + " " + \
                attribute.name + ", "
        call = call + attribute.name + ", "
      proto = string.rstrip(proto, ", ")
      call = string.rstrip(call, ", ")
      print "    void\tadd_" + inst.opcode + "(" + proto + ")"
      print "    {"
      call = "* new " + class_id(inst.opcode) + "(" + call + ")"
      print "      _program->text_section().add_inst (" + call + ");"
124
125
126
127
128
129
130
131
      if inst.kind == "branch":
        print "      if (fill_delay_slot_p)"
        print "	_program->text_section()."
        print "	  add_inst (* new Sll(* new Register(Register::general, " + \
              "Cpu::zero), "
        print "			      * new Register(Register::general, " + \
              "Cpu::zero), "
        print "			      * new IntExp(0)));"
Benoit Perrot's avatar
Benoit Perrot committed
132
133
134
      print "    }"
      
    else: # syntax.level == "complex"
135
136
137
138
139
140
141
142
143
144
145
146
      proto = ""
      for param in syntax.params:
        proto = proto + type_map[param.kind]
        if param.name:
          proto = proto + " " + param.name
        proto = proto + ", "
      proto = string.rstrip(proto, ", ")
      print "    void\tadd_" + inst.opcode + "(" + proto + ");"
      
print """
  protected:
    Program*		_program;
147
    bool                fill_delay_slot_p;
148
149
150
151
152
  };

} // namespace inst

#endif // !INST_PROGRAM_BUILDER_HH"""