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

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v5/] [software/] [CC64/] [source/] [GenerateBitfield.cpp] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2012-2018  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch<remove>@finitron.ca
6
//       ||
7
//
8
// CC64 - 'C' derived language compiler
9
//  - 64 bit CPU
10
//
11
// This source file is free software: you can redistribute it and/or modify 
12
// it under the terms of the GNU Lesser General Public License as published 
13
// by the Free Software Foundation, either version 3 of the License, or     
14
// (at your option) any later version.                                      
15
//                                                                          
16
// This source file is distributed in the hope that it will be useful,      
17
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
18
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
19
// GNU General Public License for more details.                             
20
//                                                                          
21
// You should have received a copy of the GNU General Public License        
22
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
23
//                                                                          
24
// ============================================================================
25
//
26
#include "stdafx.h"
27
#define SUPPORT_BITFIELD        false
28
 
29
static void SignExtendBitfield(ENODE *node, Operand *ap3, uint64_t mask)
30
{
31
        Operand *ap2;
32
        uint64_t umask;
33
 
34
        umask = 0x8000000000000000LL | ~(mask >> 1);
35
        ap2 = GetTempRegister();
36
        GenerateDiadic(op_ldi,0,ap2,make_immed(umask));
37
        GenerateTriadic(op_add,0,ap3,ap3,ap2);
38
        GenerateTriadic(op_xor,0,ap3,ap3,ap2);
39
        ReleaseTempRegister(ap2);
40
}
41
 
42
Operand *GenerateBitfieldDereference(ENODE *node, int flags, int size)
43
{
44
    Operand *ap, *ap3;
45
    int width = node->bit_width + 1;
46
        int isSigned;
47
        uint64_t mask;
48
 
49
        isSigned = node->nodetype==en_wfieldref || node->nodetype==en_hfieldref || node->nodetype==en_cfieldref || node->nodetype==en_bfieldref;
50
        mask = 0;
51
        while (--width) mask = mask + mask + 1;
52
        ap3 = GetTempRegister();
53
        ap3->tempflag = TRUE;
54
    ap = GenerateDereference(node, flags, node->esize, isSigned);
55
    ap->MakeLegal(flags, node->esize);
56
        if (ap->mode == am_reg)
57
                GenerateDiadic(op_mov, 0, ap3, ap);
58
        else if (ap->mode == am_imm)
59
                GenerateDiadic(op_ldi, 0, ap3, ap);
60
        else    // memory
61
                GenLoad(ap3, ap, node->esize, node->esize);
62
//      ReleaseTempRegister(ap);
63
        if (SUPPORT_BITFIELD) {
64
                if (isSigned)
65
                        Generate4adic(op_bfext,0,ap3, ap3, make_immed((int) node->bit_offset), make_immed((int)(node->bit_width-1)));
66
                else
67
                        Generate4adic(op_bfextu,0,ap3, ap3, make_immed((int) node->bit_offset), make_immed((int)(node->bit_width-1)));
68
        }
69
        else {
70
                if (node->bit_offset > 0)
71
                        GenerateTriadic(op_shru, 0, ap3, ap3, make_immed((int) node->bit_offset));
72
                GenerateTriadic(op_and, 0, ap3, ap3, make_immed(mask));
73
                if (isSigned)
74
                        SignExtendBitfield(node, ap3, mask);
75
        }
76
        ap3->MakeLegal(flags, node->esize);
77
        ap3->next = ap;
78
        ap3->offset = node;
79
    return (ap3);
80
}
81
 
82
void GenerateBitfieldInsert(Operand *ap1, Operand *ap2, int offset, int width)
83
{
84
        int nn;
85
        uint64_t mask;
86
 
87
        /* Processor doesn't support bitfield insert except for immediates
88
        if (SUPPORT_BITFIELD)
89
                Generate4adic(op_bfins,0,ap1,ap2,make_immed(offset), make_immed(width-1));
90
        else
91
        */
92
        {
93
                for (mask = nn = 0; nn < width; nn++)
94
                        mask = (mask << 1) | 1;
95
                mask = ~mask;
96
                GenerateDiadic(op_and,0,ap2,make_immed(~mask));          // clear unwanted bits in source
97
                if (offset > 0)
98
                        GenerateTriadic(op_ror,0,ap1,ap1,make_immed(offset));
99
                GenerateTriadic(op_and,0,ap1,ap1,make_immed(mask));              // clear bits in target field
100
                GenerateTriadic(op_or,0,ap1,ap1,ap2);
101
                if (offset > 0)
102
                        GenerateTriadic(op_rol,0,ap1,ap1,make_immed(offset));
103
        }
104
}
105
 
106
Operand *GenerateBitfieldAssign(ENODE *node, int flags, int size)
107
{
108
        Operand *ap1, *ap2 ,*ap3;
109
 
110
        // we don't want a bitfield dereference operation here.
111
        // We want all the bits.
112
        ap1 = GenerateExpression(node->p[0],F_REG|F_MEM|BF_ASSIGN,size);
113
        ap2 = GenerateExpression(node->p[1],F_REG,size);
114
        if (ap1->mode == am_reg) {
115
                GenerateBitfieldInsert(ap1, ap2, node->p[0]->bit_offset, node->p[0]->bit_width);
116
        }
117
        else {
118
                ap3 = GetTempRegister();
119
                GenLoad(ap3,ap1,size,size);
120
                GenerateBitfieldInsert(ap3, ap2, node->p[0]->bit_offset, node->p[0]->bit_width);
121
                GenStore(ap3,ap1,size);
122
                ReleaseTempRegister(ap3);
123
        }
124
        ReleaseTempRegister(ap2);
125
        ap1->MakeLegal( flags, size);
126
        return ap1;
127
}
128
 

powered by: WebSVN 2.1.0

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