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

Subversion Repositories raptor64

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

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 51 robfinch
        AMODE *ap1, *ap2, *ap3;
35 37 robfinch
 
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 51 robfinch
        ap3 = GetTempRegister();
57 37 robfinch
        if (ap2->mode==am_immed) {
58
                switch(op)
59
                {
60
                case op_shl:    op = op_shli; break;
61
                case op_shr:    op = op_shri; break;
62
                case op_shru:   op = op_shrui; break;
63
                }
64 51 robfinch
                GenerateTriadic(op,0,ap3,ap1,make_immed(ap2->offset->i));
65 37 robfinch
        }
66
        else
67 51 robfinch
                GenerateTriadic(op,0,ap3,ap1,ap2);
68
    ReleaseTempRegister(ap1);
69 37 robfinch
    ReleaseTempRegister(ap2);
70 51 robfinch
    MakeLegalAmode(ap3,flags,size);
71
    return ap3;
72 37 robfinch
}
73
 
74
 
75
/*
76
 *      generate shift equals operators.
77
 */
78
struct amode *GenerateAssignShift(ENODE *node,int flags,int size,int op)
79
{
80
        struct amode    *ap1, *ap2, *ap3;
81
 
82
    ap3 = GenerateExpression(node->p[0],F_ALL,size);
83
    ap2 = GenerateExpression(node->p[1],F_REG | F_IMMED,size);
84
        if (ap3->mode != am_reg) {
85
                ap1 = GetTempRegister();
86
                GenerateDiadic(op_lw,0,ap1,ap3);
87
        }
88
        else
89
                ap1 = ap3;
90
        switch(op) {
91
        case op_shru:
92
                switch (size) {
93
                        case 8:         GenerateTriadic(op_andi,0,ap1,ap1,make_immed(0xff)); break;
94
                        case 16:        GenerateTriadic(op_andi,0,ap1,ap1,make_immed(0xffff)); break;
95
                        case 32:        GenerateTriadic(op_andi,0,ap1,ap1,make_immed(0xffffffff)); break;
96
                        default:        ;
97
                }
98
                break;
99
        case op_shr:
100
                switch (size) {
101
                        case 8:         GenerateTriadic(op_sext8,0,ap1,ap1,NULL); break;
102
                        case 16:        GenerateTriadic(op_sext16,0,ap1,ap1,NULL); break;
103
                        case 32:        GenerateTriadic(op_sext32,0,ap1,ap1,NULL); break;
104
                        default:        ;
105
                }
106
                break;
107
        }
108
        if (ap2->mode==am_immed)
109
                GenerateTriadic(op,0,ap1,ap1,make_immed(ap2->offset->i));
110
        else
111
                GenerateTriadic(op,0,ap1,ap1,ap2);
112
        if (ap3->mode != am_reg) {
113
                GenerateDiadic(op_sw,0,ap1,ap3);
114
        }
115
    ReleaseTempRegister(ap2);
116
    MakeLegalAmode(ap1,flags,size);
117
    return ap1;
118
}
119
 

powered by: WebSVN 2.1.0

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