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

Subversion Repositories leros

[/] [leros/] [trunk/] [java/] [tools/] [src/] [grammar/] [Leros.g] - Diff between revs 3 and 4

Show entire file | Details | Blame | View Log

Rev 3 Rev 4
?rev1line?
?rev2line?
 
/*
 
   Copyright 2011 Martin Schoeberl ,
 
                  Technical University of Denmark, DTU Informatics.
 
   All rights reserved.
 
 
 
   Redistribution and use in source and binary forms, with or without
 
   modification, are permitted provided that the following conditions are met:
 
 
 
      1. Redistributions of source code must retain the above copyright notice,
 
         this list of conditions and the following disclaimer.
 
 
 
      2. Redistributions in binary form must reproduce the above copyright
 
         notice, this list of conditions and the following disclaimer in the
 
         documentation and/or other materials provided with the distribution.
 
 
 
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS
 
   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
 
   NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
 
   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 
   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 
   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 
   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 
   The views and conclusions contained in the software and documentation are
 
   those of the authors and should not be interpreted as representing official
 
   policies, either expressed or implied, of the copyright holder.
 
 */
 
 
 
//
 
// Grammar and lexical rules for the Leros assembler
 
// Start with a copy of Patmos
 
 
 
grammar Leros;
 
 
 
@header {
 
package leros.asm.generated;
 
 
 
import java.util.HashMap;
 
import java.util.List;
 
 
 
}
 
 
 
@lexer::header {package leros.asm.generated;}
 
 
 
 
 
@members {
 
/** Map symbol to Integer object holding the value or address */
 
HashMap symbols = new HashMap();
 
// Mapping of register names
 
HashMap reg = new HashMap();
 
int pc = 0;
 
int code[];
 
boolean pass2 = false;
 
 
 
static {
 
        // some default names for registers
 
        for (int i=0; i<16; ++i) {
 
//              reg.put("r"+i, new Integer(i));
 
        }
 
}
 
 
 
public static String niceHex(int val) {
 
        String s = Integer.toHexString(val);
 
        while (s.length() < 4) {
 
                s = "0"+s;
 
        }
 
        s = "0x"+s;
 
        return s;
 
}
 
}
 
 
 
pass1: statement+;
 
 
 
dump: {System.out.println(symbols);};
 
 
 
// Don't know how to return a simple int array :-(
 
pass2 returns [List mem]
 
@init{
 
        System.out.println(pc+" "+symbols);
 
        code = new int[pc];
 
        pc = 0;
 
        pass2 = true;
 
}
 
        : statement+ {
 
        $mem = new ArrayList(pc);
 
        for (int i=0; i
 
                $mem.add(new Integer(code[i]));
 
        }
 
        };
 
 
 
statement: (label)? (directive | instruction)? (COMMENT)? NEWLINE;
 
 
 
label:  ID ':' {symbols.put($ID.text, new Integer(pc));};
 
 
 
// just a dummy example
 
directive: '.start';
 
 
 
instruction: instr
 
        {
 
                System.out.println(pc+" "+niceHex($instr.opc));
 
                if (pass2) { code[pc] = $instr.opc; }
 
                ++pc;
 
        };
 
 
 
// Is this additional rule needed to get all values up to instruction?
 
instr returns [int opc] :
 
        simple {$opc = $simple.opc;} |
 
        alu register {$opc = $alu.value + $register.value;} |
 
        alu imm_val {$opc = $alu.value + $imm_val.value + 0x0100;} |
 
        branch {$opc = $branch.opc;} |
 
        io imm_val {$opc = $io.value + $imm_val.value;} |
 
        loadaddr register {$opc = $loadaddr.value + $register.value;} |
 
        memind {$opc = $memind.value;}
 
;
 
 
 
simple returns [int opc]:
 
        'nop'    {$opc = 0x0000;} |
 
        'shr'    {$opc = 0x1000;}
 
        ;
 
 
 
alu returns [int value]:
 
        'add'    {$value = 0x0800;} |
 
        'sub'    {$value = 0x0c00;} |
 
        'load'   {$value = 0x2000;} |
 
        'and'    {$value = 0x2200;} |
 
        'or'     {$value = 0x2400;} |
 
        'xor'    {$value = 0x2600;} |
 
        'loadh'  {$value = 0x2800;} |
 
        'store'  {$value = 0x3000;} | // TODO: no immediate version
 
        'jal'    {$value = 0x4000;} // no immediate version
 
        ;
 
 
 
io returns [int value]:
 
        'out'    {$value = 0x3800;} |
 
        'in'     {$value = 0x3c00;}
 
        ;
 
 
 
loadaddr returns [int value]:
 
        'loadaddr' {$value = 0x5000;}
 
        ;
 
 
 
memind returns [int value]:
 
        'load' '(' 'ar' '+' imm_val ')' {$value = 0x6000 + $imm_val.value;} |
 
        'store' '(' 'ar' '+' imm_val ')' {$value = 0x7000 + $imm_val.value;}
 
        ;
 
 
 
branch returns [int opc]:
 
        brinstr ID
 
        {
 
                int off = 0;
 
                if (pass2) {
 
                        Integer v = (Integer) symbols.get($ID.text);
 
                        if ( v!=null ) {
 
                                off = v.intValue();
 
                        } else {
 
                                throw new Error("Undefined label "+$ID.text);
 
                        }
 
                        off = off - pc;
 
                        // TODO test maximum offset
 
                        // at the moment 8 bits offset
 
                        off &= 0xff;
 
                }
 
                $opc = $brinstr.value + off;
 
        };
 
 
 
brinstr returns [int value]:
 
        'branch' {$value = 0x4800;} |
 
        'brz' {$value = 0x4900;} |
 
        'brnz' {$value = 0x4a00;} |
 
        'brp' {$value = 0x4b00;} |
 
        'brn' {$value = 0x4c00;}
 
        ;
 
 
 
// shall use register symbols form the HashMap
 
register returns [int value]:
 
        REG {$value = Integer.parseInt($REG.text.substring(1));
 
                if ($value<0 || $value>255) throw new Error("Wrong register name");};
 
 
 
// at the moment just 8 bit immediate
 
// can be signed or unsigned
 
imm_val returns [int value]:
 
        INT {$value = Integer.parseInt($INT.text);
 
                if ($value<-128 || $value>255) throw new Error("Wrong immediate");} |
 
        '-' INT {$value = (-Integer.parseInt($INT.text)) & 0xff;
 
                if ($value<-128 || $value>255) throw new Error("Wrong immediate");} |
 
        '<' ID
 
        {
 
                int val = 0;
 
                if (pass2) {
 
                        Integer v = (Integer) symbols.get($ID.text);
 
                        if ( v!=null ) {
 
                                val = v.intValue() & 0xff;
 
                        } else {
 
                                throw new Error("Undefined label "+$ID.text);
 
                        }
 
                }
 
                $value = val;
 
        } |
 
        '>' ID
 
        {
 
                int val = 0;
 
                if (pass2) {
 
                        Integer v = (Integer) symbols.get($ID.text);
 
                        if ( v!=null ) {
 
                                val = (v.intValue()>>8) & 0xff;
 
                        } else {
 
                                throw new Error("Undefined label "+$ID.text);
 
                        }
 
                }
 
                $value = val;
 
        }
 
        ;
 
 
 
 
 
 
 
 
 
 
 
 
 
/* Lexer rules (start with upper case) */
 
 
 
INT :  '0'..'9'+ ;
 
REG: 'r' INT;
 
//SINT: '-'? INT;
 
 
 
ID: ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_' | '0'..'9')*;
 
 
 
COMMENT: '//' ~('\n'|'\r')* ;
 
 
 
NEWLINE: '\r'? '\n' ;
 
WHITSPACE:   (' '|'\t')+ {skip();} ;
 
 

powered by: WebSVN 2.1.0

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