OpenCores
URL https://opencores.org/ocsvn/leros/leros/trunk

Subversion Repositories leros

[/] [leros/] [trunk/] [java/] [tools/] [src/] [grammar/] [Leros.g] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 martin
/*
2
   Copyright 2011 Martin Schoeberl ,
3
                  Technical University of Denmark, DTU Informatics.
4
   All rights reserved.
5
 
6
   Redistribution and use in source and binary forms, with or without
7
   modification, are permitted provided that the following conditions are met:
8
 
9
      1. Redistributions of source code must retain the above copyright notice,
10
         this list of conditions and the following disclaimer.
11
 
12
      2. Redistributions in binary form must reproduce the above copyright
13
         notice, this list of conditions and the following disclaimer in the
14
         documentation and/or other materials provided with the distribution.
15
 
16
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS
17
   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19
   NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20
   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 
27
   The views and conclusions contained in the software and documentation are
28
   those of the authors and should not be interpreted as representing official
29
   policies, either expressed or implied, of the copyright holder.
30
 */
31
 
32
//
33
// Grammar and lexical rules for the Leros assembler
34
// Start with a copy of Patmos
35
 
36
grammar Leros;
37
 
38
@header {
39
package leros.asm.generated;
40
 
41
import java.util.HashMap;
42
import java.util.List;
43
 
44
}
45
 
46
@lexer::header {package leros.asm.generated;}
47
 
48
 
49
@members {
50
/** Map symbol to Integer object holding the value or address */
51
HashMap symbols = new HashMap();
52
// Mapping of register names
53
HashMap reg = new HashMap();
54
int pc = 0;
55
int code[];
56
boolean pass2 = false;
57
 
58
static {
59
        // some default names for registers
60
        for (int i=0; i<16; ++i) {
61
//              reg.put("r"+i, new Integer(i));
62
        }
63
}
64
 
65
public static String niceHex(int val) {
66
        String s = Integer.toHexString(val);
67
        while (s.length() < 4) {
68
                s = "0"+s;
69
        }
70
        s = "0x"+s;
71
        return s;
72
}
73
}
74
 
75
pass1: statement+;
76
 
77
dump: {System.out.println(symbols);};
78
 
79
// Don't know how to return a simple int array :-(
80
pass2 returns [List mem]
81
@init{
82
        System.out.println(pc+" "+symbols);
83
        code = new int[pc];
84
        pc = 0;
85
        pass2 = true;
86
}
87
        : statement+ {
88
        $mem = new ArrayList(pc);
89
        for (int i=0; i
90
                $mem.add(new Integer(code[i]));
91
        }
92
        };
93
 
94
statement: (label)? (directive | instruction)? (COMMENT)? NEWLINE;
95
 
96
label:  ID ':' {symbols.put($ID.text, new Integer(pc));};
97
 
98
// just a dummy example
99
directive: '.start';
100
 
101
instruction: instr
102
        {
103
                System.out.println(pc+" "+niceHex($instr.opc));
104
                if (pass2) { code[pc] = $instr.opc; }
105
                ++pc;
106
        };
107
 
108
// Is this additional rule needed to get all values up to instruction?
109
instr returns [int opc] :
110
        simple {$opc = $simple.opc;} |
111
        alu register {$opc = $alu.value + $register.value;} |
112
        alu imm_val {$opc = $alu.value + $imm_val.value + 0x0100;} |
113
        branch {$opc = $branch.opc;} |
114
        io imm_val {$opc = $io.value + $imm_val.value;} |
115
        loadaddr register {$opc = $loadaddr.value + $register.value;} |
116
        memind {$opc = $memind.value;}
117
;
118
 
119
simple returns [int opc]:
120
        'nop'    {$opc = 0x0000;} |
121
        'shr'    {$opc = 0x1000;}
122
        ;
123
 
124
alu returns [int value]:
125
        'add'    {$value = 0x0800;} |
126
        'sub'    {$value = 0x0c00;} |
127
        'load'   {$value = 0x2000;} |
128
        'and'    {$value = 0x2200;} |
129
        'or'     {$value = 0x2400;} |
130
        'xor'    {$value = 0x2600;} |
131
        'loadh'  {$value = 0x2800;} |
132
        'store'  {$value = 0x3000;} | // TODO: no immediate version
133
        'jal'    {$value = 0x4000;} // no immediate version
134
        ;
135
 
136
io returns [int value]:
137
        'out'    {$value = 0x3800;} |
138
        'in'     {$value = 0x3c00;}
139
        ;
140
 
141
loadaddr returns [int value]:
142
        'loadaddr' {$value = 0x5000;}
143
        ;
144
 
145
memind returns [int value]:
146
        'load' '(' 'ar' '+' imm_val ')' {$value = 0x6000 + $imm_val.value;} |
147
        'store' '(' 'ar' '+' imm_val ')' {$value = 0x7000 + $imm_val.value;}
148
        ;
149
 
150
branch returns [int opc]:
151
        brinstr ID
152
        {
153
                int off = 0;
154
                if (pass2) {
155
                        Integer v = (Integer) symbols.get($ID.text);
156
                        if ( v!=null ) {
157
                                off = v.intValue();
158
                        } else {
159
                                throw new Error("Undefined label "+$ID.text);
160
                        }
161
                        off = off - pc;
162
                        // TODO test maximum offset
163
                        // at the moment 8 bits offset
164
                        off &= 0xff;
165
                }
166
                $opc = $brinstr.value + off;
167
        };
168
 
169
brinstr returns [int value]:
170
        'branch' {$value = 0x4800;} |
171
        'brz' {$value = 0x4900;} |
172
        'brnz' {$value = 0x4a00;} |
173
        'brp' {$value = 0x4b00;} |
174
        'brn' {$value = 0x4c00;}
175
        ;
176
 
177
// shall use register symbols form the HashMap
178
register returns [int value]:
179
        REG {$value = Integer.parseInt($REG.text.substring(1));
180
                if ($value<0 || $value>255) throw new Error("Wrong register name");};
181
 
182
// at the moment just 8 bit immediate
183
// can be signed or unsigned
184
imm_val returns [int value]:
185
        INT {$value = Integer.parseInt($INT.text);
186
                if ($value<-128 || $value>255) throw new Error("Wrong immediate");} |
187
        '-' INT {$value = (-Integer.parseInt($INT.text)) & 0xff;
188
                if ($value<-128 || $value>255) throw new Error("Wrong immediate");} |
189
        '<' ID
190
        {
191
                int val = 0;
192
                if (pass2) {
193
                        Integer v = (Integer) symbols.get($ID.text);
194
                        if ( v!=null ) {
195
                                val = v.intValue() & 0xff;
196
                        } else {
197
                                throw new Error("Undefined label "+$ID.text);
198
                        }
199
                }
200
                $value = val;
201
        } |
202
        '>' ID
203
        {
204
                int val = 0;
205
                if (pass2) {
206
                        Integer v = (Integer) symbols.get($ID.text);
207
                        if ( v!=null ) {
208
                                val = (v.intValue()>>8) & 0xff;
209
                        } else {
210
                                throw new Error("Undefined label "+$ID.text);
211
                        }
212
                }
213
                $value = val;
214
        }
215
        ;
216
 
217
 
218
 
219
 
220
 
221
 
222
/* Lexer rules (start with upper case) */
223
 
224
INT :  '0'..'9'+ ;
225
REG: 'r' INT;
226
//SINT: '-'? INT;
227
 
228
ID: ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_' | '0'..'9')*;
229
 
230
COMMENT: '//' ~('\n'|'\r')* ;
231
 
232
NEWLINE: '\r'? '\n' ;
233
WHITSPACE:   (' '|'\t')+ {skip();} ;
234
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.