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

Subversion Repositories raptor64

[/] [raptor64/] [trunk/] [software/] [c64/] [source/] [GenerateShift.c] - Blame information for rev 37

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 37 robfinch
// ============================================================================
2
// (C) 2012 Robert Finch
3
// All Rights Reserved.
4
// robfinch<remove>@opencores.org
5
//
6
// C64 - Raptor64 'C' derived language compiler
7
//  - 64 bit CPU
8
//
9
// This source file is free software: you can redistribute it and/or modify 
10
// it under the terms of the GNU Lesser General Public License as published 
11
// by the Free Software Foundation, either version 3 of the License, or     
12
// (at your option) any later version.                                      
13
//                                                                          
14
// This source file is distributed in the hope that it will be useful,      
15
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
16
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
17
// GNU General Public License for more details.                             
18
//                                                                          
19
// You should have received a copy of the GNU General Public License        
20
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
21
//                                                                          
22
// ============================================================================
23
//
24
#include <stdio.h>
25
#include "c.h"
26
#include "expr.h"
27
#include "Statement.h"
28
#include "gen.h"
29
#include "cglbdec.h"
30
 
31
 
32
AMODE *GenerateShift(ENODE *node,int flags, int size, int op)
33
{
34
        AMODE *ap1, *ap2;
35
 
36
    ap1 = GenerateExpression(node->p[0],F_REG,size);
37
    ap2 = GenerateExpression(node->p[1],F_REG | F_IMMED,8);
38
        switch(op) {
39
        case op_shru:
40
                switch (size) {
41
                        case 8:         GenerateTriadic(op_andi,0,ap1,ap1,make_immed(0xff)); break;
42
                        case 16:        GenerateTriadic(op_andi,0,ap1,ap1,make_immed(0xffff)); break;
43
                        case 32:        GenerateTriadic(op_andi,0,ap1,ap1,make_immed(0xffffffff)); break;
44
                        default:        ;
45
                }
46
                break;
47
        case op_shr:
48
                switch (size) {
49
                        case 8:         GenerateTriadic(op_sext8,0,ap1,ap1,NULL); break;
50
                        case 16:        GenerateTriadic(op_sext16,0,ap1,ap1,NULL); break;
51
                        case 32:        GenerateTriadic(op_sext32,0,ap1,ap1,NULL); break;
52
                        default:        ;
53
                }
54
                break;
55
        }
56
        if (ap2->mode==am_immed) {
57
                switch(op)
58
                {
59
                case op_shl:    op = op_shli; break;
60
                case op_shr:    op = op_shri; break;
61
                case op_shru:   op = op_shrui; break;
62
                }
63
                GenerateTriadic(op,0,ap1,ap1,make_immed(ap2->offset->i));
64
        }
65
        else
66
                GenerateTriadic(op,0,ap1,ap1,ap2);
67
    ReleaseTempRegister(ap2);
68
    MakeLegalAmode(ap1,flags,size);
69
    return ap1;
70
}
71
 
72
 
73
/*
74
 *      generate shift equals operators.
75
 */
76
struct amode *GenerateAssignShift(ENODE *node,int flags,int size,int op)
77
{
78
        struct amode    *ap1, *ap2, *ap3;
79
 
80
    ap3 = GenerateExpression(node->p[0],F_ALL,size);
81
    ap2 = GenerateExpression(node->p[1],F_REG | F_IMMED,size);
82
        if (ap3->mode != am_reg) {
83
                ap1 = GetTempRegister();
84
                GenerateDiadic(op_lw,0,ap1,ap3);
85
        }
86
        else
87
                ap1 = ap3;
88
        switch(op) {
89
        case op_shru:
90
                switch (size) {
91
                        case 8:         GenerateTriadic(op_andi,0,ap1,ap1,make_immed(0xff)); break;
92
                        case 16:        GenerateTriadic(op_andi,0,ap1,ap1,make_immed(0xffff)); break;
93
                        case 32:        GenerateTriadic(op_andi,0,ap1,ap1,make_immed(0xffffffff)); break;
94
                        default:        ;
95
                }
96
                break;
97
        case op_shr:
98
                switch (size) {
99
                        case 8:         GenerateTriadic(op_sext8,0,ap1,ap1,NULL); break;
100
                        case 16:        GenerateTriadic(op_sext16,0,ap1,ap1,NULL); break;
101
                        case 32:        GenerateTriadic(op_sext32,0,ap1,ap1,NULL); break;
102
                        default:        ;
103
                }
104
                break;
105
        }
106
        if (ap2->mode==am_immed)
107
                GenerateTriadic(op,0,ap1,ap1,make_immed(ap2->offset->i));
108
        else
109
                GenerateTriadic(op,0,ap1,ap1,ap2);
110
        if (ap3->mode != am_reg) {
111
                GenerateDiadic(op_sw,0,ap1,ap3);
112
        }
113
    ReleaseTempRegister(ap2);
114
    MakeLegalAmode(ap1,flags,size);
115
    return ap1;
116
}
117
 

powered by: WebSVN 2.1.0

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