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

Subversion Repositories forwardcom

[/] [forwardcom/] [bintools/] [assem2.cpp] - Blame information for rev 42

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 42 Agner
/****************************    assem2.cpp    ********************************
2
* Author:        Agner Fog
3
* Date created:  2017-04-17
4
* Last modified: 2021-08-11
5
* Version:       1.11
6
* Project:       Binary tools for ForwardCom instruction set
7
* Module:        assem.cpp
8
* Description:
9
* Module for assembling ForwardCom .as files.
10
* This module contains:
11
* - expression(): Interpretation of expressions containing operators and
12
*                 any type of operands.
13
* Copyright 2017-2021 GNU General Public License http://www.gnu.org/licenses
14
******************************************************************************/
15
#include "stdafx.h"
16
 
17
 
18
// Interpret and evaluate expression
19
SExpression CAssembler::expression(uint32_t tok1, uint32_t maxtok, uint32_t options) {
20
    // tok1: index to first token, 
21
    // maxtok: maximum number of tokens to use, 
22
    // options: 0: normal, 
23
    // 1: unsigned
24
    // 2: inside []. interpret as memory operand
25
    // 4: interpret option = keyword
26
    // 8: inside {}. has no meaning yet
27
    // 0x10: check syntax and count tokens, but do not call functions or report numeric 
28
    //       overflow, wrong operand types, or unknown names
29
 
30
    // This function scans the tokens and finds the operator with lowest priority. 
31
    // The function is called recursively for each operand to this operator.
32
    // The level of parantheses is saved in the brackets stack.
33
    // The scanning terminates at any of these conditions:
34
    // * a token that cannot be part of the expression is encountered
35
    // * all tokens are used
36
    // * a comma is encountered
37
    // * an unmatched end bracket is encountered
38
 
39
    uint32_t tok;                 // current token
40
    uint32_t toklow = tok1;       // operator with lowest priority
41
    uint32_t tokcolon = 0;        // matching triadic operator with lowest priority
42
    uint32_t ntok = 0;            // number of tokens used
43
    uint32_t priority = 0;        // priority of this operator
44
    uint32_t bracketlevel = 0;    // number of brackets in stack
45
    uint32_t state = 0;           // 0: expecting value, 1: after value, expecting operator or end
46
    uint32_t i;                   // loop counter
47
    uint32_t temp;                // temporary result
48
    uint32_t tokid;               // token.id
49
    int32_t  symi;                // symbol index
50
    bool     is_local = false;    // symbol is local constant
51
    uint8_t  endbracket;          // expected end bracket
52
 
53
    SExpression exp1, exp2;       // expressions during evaluation
54
    zeroAllMembers(exp1);         // reset exp1
55
    exp1.tokens = 1;
56
 
57
    for (tok = tok1; tok < tok1 + maxtok; tok++) {
58
        if (lineError) {exp1.etype = 0;  return exp1;}
59
        if (tokens[tok].type == TOK_OPR) {
60
            // operator found. search for brackets
61
            if (tokens[tok].priority == 1 || tokens[tok].priority == 14) {
62
                // bracket found. ?: operator treated as bracket here                
63
                switch (tokens[tok].id) {
64
                case '?':
65
                    if (tokens[tok].priority > priority && bracketlevel == 0) {  // if multiple ?:, split by the last one
66
                        priority = tokens[tok].priority; toklow = tok;
67
                    }
68
                    // continue in next case
69
                case '(': case '[': case '{':  // opening bracket. push on bracket stack
70
                    brackets.push(uint8_t(tokens[tok].id));
71
                    bracketlevel++;
72
                    state = 0;
73
                    break;
74
                case ')': case ']': case '}': case ':': // closing bracket
75
                    if (bracketlevel == 0) {
76
                        goto EXIT_LOOP;     // this end bracket is not part of the expression.
77
                    }
78
                    // remove matching opening bracket from stack
79
                    bracketlevel--;
80
                    endbracket = brackets.pop();
81
                    switch (endbracket) {
82
                    case '(':  endbracket = ')';  break;
83
                    case '[':  endbracket = ']';  break;
84
                    case '{':  endbracket = '}';  break;
85
                    case '?':  endbracket = ':';  break;
86
                    }
87
                    if (endbracket != tokens[tok].id) {
88
                        // end bracket does not match begin bracket
89
                        errors.report(tokens[tok].pos, tokens[tok].stringLength, ERR_BRACKET_END);
90
                        goto EXIT_LOOP;
91
                    }
92
                    if (tokens[tok].id == ':') {
93
                        if (bracketlevel == 0 && priority == 14 && tokcolon == 0) {
94
                            tokcolon = tok; // ':' matches current '?' with lowest priority
95
                        }
96
                        state = 0;
97
                        continue;
98
                    }
99
                    state = 1;
100
                    continue;  // finished with this token                
101
                }
102
            }
103
            if (bracketlevel) continue;  // don't search for priority inside brackets
104
 
105
            if (state == 1) {
106
                // expecting operator
107
                if (tokens[tok].id == ';') break;  // end at semicolon
108
                if (tokens[tok].id == ',' && !(options & 2)) break;  // end at comma, except inside []
109
                if (tokens[tok].id == '=' && !(options & 6)) break;  // end at =, except inside [] or when interpreting option = value
110
 
111
                if (tokens[tok].priority >= priority) {  // if multiple operators with same priority, split by the last one to get the first evaluated first
112
                    // operator with lower priority found
113
                    priority = tokens[tok].priority;
114
                    toklow = tok;
115
                }
116
                if (tokens[tok].priority == 3) state = 1; else state = 0;  // state 0 except after monadic operator
117
            }
118
            else if (state == 0 && (tokens[tok].id == '-' || tokens[tok].id == '+' || tokens[tok].priority == 3)) {
119
                // monadic operator
120
                if (priority < 3) {
121
                    priority = 3;  toklow = tok;
122
                }
123
            }
124
            else {
125
                errors.report(tokens[tok]);  break;  // unexpected operator
126
            }
127
        }
128
        else {
129
            // not an operator
130
            if (bracketlevel) continue;  // inside brackets: search only for end bracket
131
            if (state == 0) {
132
                // expecting value
133
                switch (tokens[tok].type) {
134
                case TOK_NAM: case TOK_LAB: case TOK_VAR: case TOK_SEC:
135
                case TOK_NUM: case TOK_FLT: case TOK_CHA: case TOK_STR:
136
                case TOK_REG: case TOK_SYM: case TOK_XPR: case TOK_OPT:
137
                    state = 1; // allowed value tokens
138
                    break;
139
                case TOK_TYP:
140
                    state = 1; // type expression
141
                    break;
142
                case TOK_HLL:
143
                    if (tokens[tok].id == HLL_FALSE || tokens[tok].id == HLL_TRUE) {
144
                        state = 1;
145
                    }
146
                    else {
147
                        errors.report(tokens[tok]);
148
                    }
149
                    break;
150
                default:
151
                    errors.report(tokens[tok]);  break;
152
                }
153
            }
154
            else {
155
                break;    // no operator found after value. end here
156
            }
157
        }
158
    }
159
    EXIT_LOOP:
160
    if (lineError) {exp1.etype = 0;  return exp1;}
161
    // number of tokens used
162
    ntok = tok - tok1;
163
    exp1.tokens = ntok;
164
    if (bracketlevel) {
165
        endbracket = brackets.pop();
166
        errors.report(tokens[tok1].pos, tokens[tok].pos - tokens[tok1].pos, endbracket == '?' ? ERR_QUESTION_MARK : ERR_BRACKET_BEGIN);
167
        if (exp1.etype == 0) exp1.etype = XPR_INT;
168
        return exp1;
169
    }
170
    if (ntok == 0) {  // no expression found
171
        if (maxtok == 0 && tok > 0) tok--;
172
        errors.report(tokens[tok].pos, tokens[tok].stringLength, ERR_MISSING_EXPR);
173
        return exp1;
174
    }
175
 
176
    switch (priority) {
177
    case 0:  // no operator found. just an expression
178
        if (ntok > 2 && tokens[tok1].type == TOK_OPR && tokens[tok1].priority == 1) {
179
            // this is an expression in brackets
180
            uint32_t option1 = options;
181
            if (tokens[tok1].id == '[') {
182
                if (options & 2) errors.report(tokens[tok1]); // nested [[]] not allowed
183
                option1 |= 2;
184
            }
185
            if (tokens[tok1].id == '{') option1 |= 8;
186
            // evaluate expression inside bracket
187
            exp1 = expression(tok1 + 1, ntok - 2, option1);
188
            exp1.tokens += 2;
189
            goto RETURNEXP1;
190
        }
191
        else if (ntok == 1) {
192
            // this is a single token. get value
193
            switch (tokens[tok1].type) {
194
            case TOK_LAB: case TOK_VAR: case TOK_SEC: case TOK_SYM:
195
                exp1.etype = XPR_SYM1;            // symbol address
196
                exp1.sym3 = tokens[tok1].id;
197
                symi = findSymbol(exp1.sym3);
198
                // is symbol local with known value?
199
                is_local = symi > 0 && symbols[symi].st_bind == STB_LOCAL && (symbols[symi].st_type == STT_CONSTANT || symbols[symi].st_type == STT_VARIABLE);
200
                if (options & 2) {  // symbol inside []
201
                    exp1.etype |= XPR_MEM;
202
                    exp1.sym3 = 0;
203
                    if (is_local) {
204
                        exp1.offset_mem = tokens[tok1].value.w;// don't take value from symbol, it may change
205
                        exp1.etype &= ~XPR_SYM1;               // symbol reference no longer needed
206
                        exp1.etype |= XPR_OFFSET;              // has offset
207
                    }
208
                    else {
209
                        exp1.sym1 = tokens[tok1].id;
210
                    }
211
                    if (exp1.etype & (XPR_FLT | XPR_STRING)) { // float or string not allowed in memory operand
212
                        errors.report(tokens[tok1].pos, tokens[tok1].stringLength, ERR_WRONG_TYPE);
213
                    }
214
                }
215
                else {  // symbol outside []
216
                    if (is_local) {
217
                        if (symbols[symi].st_other & STV_FLOAT) exp1.etype |= XPR_FLT;
218
                        else exp1.etype |= XPR_INT;
219
                        exp1.value.i = tokens[tok1].value.u;   // don't take value from symbol, it may change
220
                        if (symbols[symi].st_other & STV_STRING) {
221
                            exp1.etype = XPR_STRING;
222
                            exp1.sym2 = (uint32_t)symbols[symi].st_unitnum; // sym2 used for string length
223
                        }
224
                        else {
225
                            exp1.etype &= ~XPR_SYM1;            // symbol reference no longer needed
226
                            exp1.sym3 = 0;
227
                        }
228
                    }
229
                    else {
230
                        exp1.etype |= XPR_INT; // type not known yet?
231
                        exp1.sym3 = tokens[tok1].id;
232
                    }
233
                }
234
                break;
235
            case TOK_NUM:
236
                if (options & 2) { // number inside [] is offset
237
                    exp1.etype = XPR_OFFSET;  // integer value
238
                    exp1.offset_mem = (int32_t)interpretNumber((char*)buf()+tokens[tok1].pos, tokens[tok1].stringLength, &temp);
239
                }
240
                else {  // number outside [] is operand
241
                    exp1.etype = XPR_INT;  // integer value
242
                    exp1.value.i = interpretNumber((char*)buf() + tokens[tok1].pos, tokens[tok1].stringLength, &temp);
243
                }
244
                if (temp) errors.report(tokens[tok1]);
245
                break;
246
            case TOK_FLT:
247
                exp1.etype = XPR_FLT;  // floating point value
248
                exp1.value.d = interpretFloat((char*)buf()+tokens[tok1].pos, tokens[tok1].stringLength);
249
                if (options & 2) {   // float not allowed in memory operand
250
                    errors.report(tokens[tok1].pos, tokens[tok1].stringLength, ERR_WRONG_TYPE);
251
                }
252
                break;
253
            case TOK_CHA:  {          // character(s). convert to integer
254
                exp1.etype = XPR_INT;
255
                exp1.value.u = 0;
256
                bool escape = false;  // check for \ escape characters
257
                int j = 0;            // count characters
258
                for (i = 0; i < tokens[tok1].stringLength; i++) {
259
                    uint8_t c = get<uint8_t>(tokens[tok1].pos + i);
260
                    if (c == '\\' && !escape) {
261
                        escape = true; continue;           // escape next character
262
                    }
263
                    if (escape) {   // special escape characters
264
                        switch (c) {
265
                        case '\\':            break;
266
                        case 'n':  c = '\n';  break;
267
                        case 'r':  c = '\r';  break;
268
                        case 't':  c = '\t';  break;
269
                        case '0':  c = 0;     break;
270
                        }
271
                    }
272
                    escape = false;
273
                    exp1.value.u += uint64_t(c) << j*8;
274
                    j++;
275
                }
276
                if (options & 2) {   // string not allowed in memory operand
277
                    errors.report(tokens[tok1].pos, tokens[tok1].stringLength, ERR_WRONG_TYPE);
278
                }
279
                break;}
280
            case TOK_STR:  {          // string
281
                exp1.etype = XPR_STRING;
282
                exp1.value.u = stringBuffer.dataSize();    // save position of string
283
                exp1.sym2 = tokens[tok1].stringLength;     // string length
284
                bool escape = false;                       // check for \ escape characters
285
                for (i = 0; i < tokens[tok1].stringLength; i++) {
286
                    char c = get<char>(tokens[tok1].pos + i);
287
                    if (c == '\\' && !escape) {
288
                        escape = true; continue;           // escape next character
289
                    }
290
                    if (escape) {   // special escape characters
291
                        switch (c) {
292
                        case '\\':  escape = false;  break;
293
                        case 'n':  c = '\n';  break;
294
                        case 'r':  c = '\r';  break;
295
                        case 't':  c = '\t';  break;
296
                        case '0':  c = 0;     break;
297
                        }
298
                    }
299
                    if (escape && exp1.sym2) exp1.sym2--;  // reduce length
300
                    stringBuffer.put(c);
301
                    escape = false;
302
                }
303
                stringBuffer.put(char(0));                 // terminate string
304
                if (options & 2) {                         // string not allowed in memory operand
305
                    errors.report(tokens[tok1].pos, tokens[tok1].stringLength, ERR_WRONG_TYPE);
306
                }
307
                break;}
308
            case TOK_REG:
309
                if (options & 2) { // register inside [] is base register
310
                    exp1.etype = XPR_BASE | XPR_MEM;
311
                    exp1.base = uint8_t(tokens[tok1].id);
312
                    if ((tokens[tok1].id & 0xFE0) == REG_SPEC) {
313
                        exp1.base = tokens[tok1].id >> 16;  // special register. to do: check if register type is valid
314
                    }
315
                }
316
                else {             // normal register operand
317
                    exp1.etype = XPR_REG | XPR_REG1;
318
                    exp1.reg1 = tokens[tok1].id;
319
                }
320
                break;
321
            case TOK_NAM:
322
                if ((options & 0x10) == 0) errors.report(tokens[tok1]);
323
                exp1.etype |= XPR_UNRESOLV;        // unresolved name
324
                break;
325
            case TOK_OPT:
326
                exp1.etype = XPR_OPTION;
327
                if ((tokens[tok1].id) == OPT_SCALAR) {
328
                    exp1.etype |= XPR_SCALAR;
329
                }
330
                else {
331
                    exp1.value.u = tokens[tok1].id;
332
                }
333
                break;
334
            case TOK_XPR:  // expression
335
                if (tokens[tok1].value.u < expressions.numEntries()) {
336
                    exp1 = expressions[tokens[tok1].value.w];
337
                    exp1.tokens = ntok;
338
                    if ((exp1.etype & XPR_REG) && !(exp1.etype & XPR_MEM) && (options & 2)) { // register inside [] is base register
339
                        exp1.etype = XPR_BASE | XPR_MEM;
340
                        exp1.base = exp1.reg1;
341
                        exp1.reg1 = 0;
342
                    }
343
                }
344
                else errors.report(tokens[tok1]);
345
                break;
346
            case TOK_TYP:
347
                exp1.etype = XPR_TYPENAME;
348
                exp1.value.u = tokens[tok1].id;
349
                break;
350
            case TOK_HLL:
351
                if (tokens[tok1].id == HLL_FALSE || tokens[tok1].id == HLL_TRUE) {  // translate to constant
352
                    exp1.etype = XPR_INT;
353
                    exp1.value.u = tokens[tok1].id & 1;
354
                }
355
                else {
356
                    errors.report(tokens[tok1]);
357
                }
358
                break;
359
            default:
360
                errors.report(tokens[tok1]);
361
            }
362
            if (options & 2) exp1.etype |= XPR_MEM;  // inside [], interpret as memory operand
363
            goto RETURNEXP1;
364
        }
365
        else {
366
            // unrecognized token
367
            errors.report(tokens[tok1]);
368
        }
369
        break;
370
 
371
    case 3:  // monadic operator
372
        if (toklow == tok1) {  // operator comes first
373
            exp1 = expression(toklow + 1, maxtok - 1, options);   // evaluate the rest
374
            if (exp1.etype & XPR_UNRESOLV) {
375
                exp1.tokens++;   // unresolved expression. return unresolved result
376
                goto RETURNEXP1;
377
            }
378
            zeroAllMembers(exp2);  // zero exp2
379
            switch (tokens[toklow].id) {
380
            case '+':            // value is unchanged
381
                exp1.tokens++;
382
                goto RETURNEXP1;;  // value is unchanged
383
            case '-':
384
                if (exp1.etype & (XPR_OP | XPR_REG | XPR_MEM)) {
385
                    exp1 = op1minus(exp1); // convert -(A+B) etc.
386
                    goto RETURNEXP1;
387
                }
388
                exp2 = exp1;      // convert -A to 0-A
389
                exp1.tokens = 0;
390
                exp1.etype = XPR_INT;
391
                exp1.value.i = 0;
392
                tokid = '-';
393
                break;  // continue in dyadic operators with 0-exp2
394
            case '!':
395
                exp1.tokens++;
396
                if (exp1.instruction == II_COMPARE
397
                && (exp1.etype & XPR_REG1) && (exp1.etype & (XPR_REG2 | XPR_INT | XPR_IMMEDIATE))) {
398
                    // compare instruction. invert condition
399
                    exp1.optionbits ^= 1;
400
                    exp1.etype |= XPR_OPTIONS;
401
                    if ((exp1.reg1 & REG_V) && (dataType & TYP_FLOAT)) exp1.optionbits ^= 8; // floating point compare. invert gives unordered
402
                    goto RETURNEXP1;
403
                }
404
                if (exp1.instruction == II_AND
405
                && (exp1.etype & XPR_REG1) && (exp1.etype & XPR_INT)) {
406
                    // test_bit/test_bits_or/jump instruction. invert condition
407
                    exp1.optionbits ^= 4;
408
                    exp1.etype |= XPR_OPTIONS;
409
                    goto RETURNEXP1;
410
                }
411
                if (exp1.instruction == II_TEST_BITS_AND && (exp1.etype & XPR_REG1) && (exp1.etype & XPR_INT)) {
412
                    // test_bits_and/jump instruction. invert condition
413
                    exp1.optionbits ^= 1;
414
                    exp1.etype |= XPR_OPTIONS;
415
                    goto RETURNEXP1;
416
                }
417
                if (exp1.etype & (XPR_MEM | XPR_REG)) { // '!' ambiguous on register and memory operands
418
                    errors.report(tokens[toklow].pos, tokens[toklow].stringLength, ERR_NOT_OP_AMBIGUOUS);
419
                }
420
                exp2.tokens = 0;
421
                exp2.etype = XPR_INT;
422
                exp2.value.i = 0;
423
                tokid = '='+D2;
424
                break;  // continue in dyadic operators with exp1 == 0
425
            case '~':
426
                exp2.tokens = 0;
427
                exp2.etype = XPR_INT;
428
                exp2.value.i = -1;
429
                tokid = '^';
430
                break;  // continue in dyadic operators with exp1 ^ -1
431
            default:
432
                errors.report(tokens[tok1]);  // ++ and -- not supported in expression
433
                return exp1;
434
            }
435
            goto DYADIC;   // proceed to dyadic operator
436
        }
437
        else {  // postfix ++ and --
438
            errors.report(tokens[tok1+1]);  // ++ and -- not supported in expression
439
        }
440
        goto RETURNEXP1;
441
 
442
    case 14: // triadic operator ?:
443
        // evaluate exp1 ? exp2 : exp3 for all expression types
444
        return op3(tok1, toklow, tokcolon, maxtok, options);
445
 
446
    default:; // continue below for dyadic operator
447
    }
448
    // dyadic operator. evaluate two subexpressions
449
    exp1 = expression(tok1, toklow - tok1, options);  // evaluate fist expression
450
    if (exp1.tokens != toklow - tok1) errors.report(tokens[tok1 + exp1.tokens]);
451
    if (lineError) return exp1;
452
 
453
    exp2 = expression(toklow + 1, tok1 + maxtok - (toklow + 1), options);  // evaluate second expression
454
    ntok = toklow - tok1 + 1 + exp2.tokens;
455
    tokid = tokens[toklow].id;  // operator id
456
    if (lineError) return exp1;
457
 
458
DYADIC:
459
    exp1 = op2(tokid, exp1, exp2);
460
 
461
    RETURNEXP1:
462
    if (lineError) return exp1;
463
    if (exp1.etype & XPR_ERROR) {
464
        errors.report(tokens[toklow].pos, tokens[toklow].stringLength, exp1.value.w);
465
    }
466
    return exp1;
467
}
468
 
469
// Interpret dyadic expression with any type of operands
470
SExpression CAssembler::op2(uint32_t op, SExpression & exp1, SExpression & exp2) {
471
 
472
    if ((exp1.etype | exp2.etype) & XPR_UNRESOLV) {
473
        exp1.etype = XPR_UNRESOLV;  // unresolved operand. make unresolved result
474
        exp1.tokens += exp2.tokens + 1;
475
    }
476
    else if ((exp1.etype & exp2.etype & XPR_MEM)
477
        //&& ((exp1.etype|exp2.etype) & (XPR_BASE|XPR_INDEX|XPR_OPTION|XPR_SYM1|XPR_SYM2|XPR_LIMIT|XPR_LENGTH|XPR_BROADC))
478
        ) {
479
        exp1 = op2Memory(op, exp1, exp2);                // generation of memory operand. both operands inside [] and contain not only constants
480
    }
481
    else if (exp1.etype == XPR_OPTION && op == '=') {
482
        // option = value is handled by op2Memory
483
        exp1 = op2Memory(op, exp1, exp2);
484
    }
485
    else if (exp1.etype & exp2.etype & XPR_SYM1) {
486
        // adding or subtracting symbols and integers
487
        exp1 = op2Memory(op, exp1, exp2);
488
    }
489
    else if ((exp1.etype & XPR_SYM2) && (exp2.etype & XPR_INT)) {
490
        // (sym1-sym2)/const
491
        exp1 = op2Memory(op, exp1, exp2);
492
    }
493
    // generation of instruction involving registers and/or memory operand:
494
    // (don't rely on XPR_MEM flag here because we would catch expressions involving constants only inside [] )
495
    //!else if ((exp1.etype | exp2.etype) & (XPR_REG | XPR_BASE /*| XPR_SYM1*/)) {
496
//    else if ((exp1.etype | exp2.etype) & (XPR_REG | XPR_BASE | XPR_SYM1)) {     //??
497
    else if (((exp1.etype | exp2.etype) & (XPR_REG | XPR_BASE)) || (exp1.sym1 | exp2.sym1)) {     //??
498
        exp1 = op2Registers(op, exp1, exp2);
499
    }
500
    else if ((exp1.etype | exp2.etype) & XPR_STRING) {
501
        exp1 = op2String(op, exp1, exp2);             // string operation
502
    }
503
    else if ((exp1.etype & 0xF) == XPR_FLT || (exp2.etype & 0xF) == XPR_FLT) {
504
        // dyadic operators for float                 // floating point operation
505
        exp1 = op2Float(op, exp1, exp2);
506
    }
507
    else if ((exp1.etype & 0xF) == XPR_INT && (exp2.etype & 0xF) == XPR_INT) {
508
        // dyadic operators for integers              // integer operation
509
        exp1 = op2Int(op, exp1, exp2);
510
    }
511
    else {
512
        // other types
513
        exp1.etype = XPR_ERROR;
514
        exp1.value.u = ERR_WRONG_TYPE;
515
    }
516
    return exp1;
517
}
518
 
519
// Interpret dyadic expression with integer operands
520
SExpression CAssembler::op2Int(uint32_t op, SExpression const & exp1, SExpression const & exp2) {
521
    SExpression expr = exp1;
522
    expr.tokens = exp1.tokens + exp2.tokens + 1;
523
    switch (op & ~OP_UNS) {
524
    case '+':
525
        expr.value.u = exp1.value.u + exp2.value.u;
526
        break;
527
    case '-':
528
        expr.value.u = exp1.value.u - exp2.value.u;
529
        break;
530
    case '*':
531
        expr.value.i = exp1.value.i * exp2.value.i;
532
        break;
533
    case '/':
534
        if (exp2.value.i == 0) {
535
            expr.etype |= XPR_ERROR;
536
            expr.value.u = ERR_OVERFLOW;
537
            break;
538
        }
539
        if (op & OP_UNS) expr.value.u = exp1.value.u / exp2.value.u; // unsigned division
540
        else  expr.value.i = exp1.value.i / exp2.value.i; // signed division
541
        break;
542
    case '%':
543
        if (exp2.value.i == 0) {
544
            expr.etype |= XPR_ERROR;
545
            expr.value.u = ERR_OVERFLOW;
546
            break;
547
        }
548
        if (op & OP_UNS) expr.value.u = exp1.value.u % exp2.value.u; // unsigned modulo
549
        else  expr.value.i = exp1.value.i % exp2.value.i; // signed modulo
550
        break;
551
    case '<' + D2:  // <<
552
        expr.value.u = exp1.value.u << exp2.value.u;
553
        break;
554
    case '>' + D2:  // >>  shift right signed
555
        if (op & OP_UNS) expr.value.u = exp1.value.u >> exp2.value.u; // unsigned shift right
556
        else  expr.value.i = exp1.value.i >> exp2.value.i; // signed shift right
557
        break;
558
    case '>' + D3:  // >>> unsigned shift right
559
        expr.value.u = exp1.value.u >> exp2.value.u;
560
        break;
561
    case '<':    // < compare
562
        if (op & OP_UNS) expr.value.i = exp1.value.u < exp2.value.u; // unsigned compare
563
        else  expr.value.i = exp1.value.i < exp2.value.i; // signed compare
564
        break;
565
    case '<' + EQ:  // <=  compare
566
        if (op & OP_UNS) expr.value.i = exp1.value.u <= exp2.value.u; // unsigned compare
567
        else  expr.value.i = exp1.value.i <= exp2.value.i; // signed compare
568
        break;
569
    case '>':    // > compare
570
        if (op & OP_UNS) expr.value.i = exp1.value.u > exp2.value.u; // unsigned compare
571
        else  expr.value.i = exp1.value.i > exp2.value.i; // signed compare
572
        break;
573
    case '>' + EQ:   // >= compare
574
        if (op & OP_UNS) expr.value.i = exp1.value.u >= exp2.value.u; // unsigned compare
575
        else  expr.value.i = exp1.value.i >= exp2.value.i; // signed compare
576
        break;
577
    case '=' + D2:   // ==
578
        expr.value.u = exp1.value.u == exp2.value.u;
579
        break;
580
    case '!' + EQ:   // !=
581
        expr.value.u = exp1.value.u != exp2.value.u;
582
        break;
583
    case '&':  // bitwise and
584
        expr.value.u = exp1.value.u & exp2.value.u;
585
        break;
586
    case '|':  // bitwise or
587
        expr.value.u = exp1.value.u | exp2.value.u;
588
        break;
589
    case '^':  // bitwise xor
590
        expr.value.u = exp1.value.u ^ exp2.value.u;
591
        break;
592
    case '&' + D2:  // logical and
593
        expr.value.u = exp1.value.u && exp2.value.u;
594
        break;
595
    case '|' + D2:  // logical or
596
        expr.value.u = exp1.value.u || exp2.value.u;
597
        break;
598
    case '^' + D2:  // logical xor
599
        expr.value.u = (exp1.value.u != 0) ^ (exp2.value.u != 0);
600
        break;
601
    default:  // unsupported operator
602
        expr.etype |= XPR_ERROR;
603
        expr.value.u = ERR_WRONG_TYPE;
604
    }
605
    return expr;
606
}
607
 
608
// Interpret dyadic expression with floating point operands
609
SExpression CAssembler::op2Float(uint32_t op, SExpression & exp1, SExpression & exp2) {
610
    SExpression expr = exp1;
611
    expr.tokens = exp1.tokens + exp2.tokens + 1;
612
    if (exp1.etype == XPR_INT) {  // convert exp1 to float
613
        exp1.value.d = (double)exp1.value.i;
614
        expr.etype = XPR_FLT;
615
    }
616
    if (exp2.etype == XPR_INT) {  // convert exp2 to float
617
        exp2.value.d = (double)exp2.value.i;
618
        expr.etype = XPR_FLT;
619
    }
620
    // dyadic operator on float
621
    switch (op) {
622
    case '+':
623
        expr.value.d = exp1.value.d + exp2.value.d;
624
        break;
625
    case '-':
626
        expr.value.d = exp1.value.d - exp2.value.d;
627
        break;
628
    case '*':
629
        expr.value.d = exp1.value.d * exp2.value.d;
630
        break;
631
    case '/':
632
        if (exp2.value.d == 0.) {
633
            expr.etype |= XPR_ERROR;
634
            expr.value.u = ERR_OVERFLOW;
635
            break;
636
        }
637
        expr.value.d = exp1.value.d / exp2.value.d;
638
        break;
639
    case '<':    // signed compare
640
        expr.value.i = exp1.value.d < exp2.value.d;
641
        expr.etype = XPR_INT;
642
        break;
643
    case '<' + EQ:  // <= signed compare
644
        expr.value.i = exp1.value.d <= exp2.value.d;
645
        expr.etype = XPR_INT;
646
        break;
647
    case '>':    // signed compare
648
        expr.value.i = exp1.value.d > exp2.value.d;
649
        expr.etype = XPR_INT;
650
        break;
651
    case '>' + EQ:   // >= signed compare
652
        expr.value.i = exp1.value.d <= exp2.value.d;
653
        expr.etype = XPR_INT;
654
        break;
655
    case '=' + D2:   // ==
656
        expr.value.i = exp1.value.d == exp2.value.d;
657
        expr.etype = XPR_INT;
658
        break;
659
    case '!' + EQ:   // !=
660
        expr.value.i = exp1.value.d != exp2.value.d;
661
        expr.etype = XPR_INT;
662
        break;
663
    case '&' + D2:  // logical and
664
        expr.value.i = exp1.value.d != 0. && exp2.value.d != 0.;
665
        expr.etype = XPR_INT;  break;
666
        break;
667
    case '|' + D2:  // logical or
668
        expr.value.i = exp1.value.d != 0. || exp2.value.d != 0.;
669
        expr.etype = XPR_INT;  break;
670
        break;
671
    default:  // unsupported operator
672
        expr.etype |= XPR_ERROR;
673
        expr.value.u = ERR_WRONG_TYPE;
674
    }
675
    return expr;
676
}
677
 
678
// Interpret dyadic expression with register or memory operands, generating instruction
679
SExpression CAssembler::op2Registers(uint32_t op, SExpression const & ex1, SExpression const & ex2) {
680
    SExpression expr = {{0}};         // return expression
681
    uint8_t swapped = false;          // operands are swapped
682
    uint8_t cannotSwap = false;       // cannot swap operands because both contain vector registers
683
    uint32_t i;                       // loop counter
684
 
685
                                      // make array of the two expressions
686
    SExpression exp12[2];             // copy of expressions
687
    uint32_t numtokens = ex1.tokens + ex2.tokens + 1; // number of tokens
688
    expr.tokens = numtokens;
689
 
690
    // resolve nested expressions
691
    if ((ex1.etype | ex2.etype) & XPR_OP) {
692
        /*
693
        if (op == '&' && (ex1.etype & XPR_REG) && !(ex1.etype & XPR_OP) && ex2.instruction == II_XOR && ((ex2.etype & 0xF) == XPR_INT) && ex2.value.i == -1) {
694
            // A & (B ^ -1) = and_not(A,B). This instruction is removed
695
            expr = ex1;  expr.tokens = numtokens;
696
            expr.etype |= XPR_OP;
697
            expr.instruction = II_AND_NOT;
698
            expr.reg2 = ex2.reg1;
699
            return expr;
700
        } */
701
        // simplify both expressions if possible
702
        exp12[0] = ex1;  exp12[1] = ex2;
703
        for (i = 0; i < 2; i++) {
704
            if ((exp12[i].etype & (XPR_REG | XPR_MEM)) && (exp12[i].etype & XPR_IMMEDIATE) && exp12[i].value.i == 0) {
705
                if (exp12[i].instruction == II_SUB_REV) {
706
                    // expression is -A converted to (0-A). change to register and sign bit
707
                    exp12[i].etype &= ~(XPR_OPTIONS | XPR_IMMEDIATE | XPR_OP);
708
                    exp12[i].instruction = 0;
709
                    exp12[i].optionbits = 1;
710
                }
711
                else if (exp12[i].instruction == II_MUL_ADD && exp12[i].value.i == 0) {
712
                    // expression is -A*B converted to (-A*B+0). change to A*B and sign bit
713
                    exp12[i].instruction = II_MUL;
714
                    exp12[i].optionbits = exp12[i].optionbits & 1;
715
                    exp12[i].etype &= ~(XPR_OPTIONS | XPR_IMMEDIATE);
716
                }
717
                else if (exp12[i].instruction == II_ADD_ADD && (exp12[i].etype & (XPR_INT | XPR_FLT)) && (exp12[i].optionbits & 3) == 3 && exp12[i].value.i == 0) {
718
                    // expression is -(A+B) converted to (-A-B+0). change to A+B and sign bit
719
                    exp12[i].etype &= ~(XPR_INT | XPR_FLT);
720
                    exp12[i].instruction = II_ADD;
721
                    exp12[i].optionbits ^= 3;
722
                    exp12[i].etype &= ~(XPR_OPTIONS | XPR_IMMEDIATE);
723
                }
724
            }
725
            else if (exp12[i].instruction == II_SUB_REV) {
726
                // change -A+B to -(A-B)
727
                exp12[i].instruction = II_SUB;
728
                exp12[i].optionbits ^= 3;
729
            }
730
        }
731
        if ((exp12[0].etype & XPR_IMMEDIATE) && (exp12[1].etype & XPR_IMMEDIATE)) {
732
            // both operands contain an immediate. combine the immediates if possible
733
 
734
            bool isfloat[2];  // check if operands are float
735
            for (i = 0; i < 2; i++) isfloat[i] = (exp12[i].etype & XPR_IMMEDIATE) == XPR_FLT;
736
 
737
            // convert integer to float if the other operand is float
738
            for (i = 0; i < 2; i++) {
739
                if (isfloat[1-i] && !isfloat[i]) {
740
                    exp12[i].value.d = (double)exp12[i].value.i;
741
                    isfloat[i] = true;
742
                }
743
            }
744
 
745
            if (op == '+' || op == '-') { // add or subtract operands and store in exp12[1]
746
                uint8_t sign = 0;
747
                switch (exp12[0].instruction) {
748
                case II_ADD: case II_SUB_REV:
749
                    sign = exp12[0].optionbits >> 1 & 1;
750
                    if (op == '-') sign ^= 1;
751
                    break;
752
                case II_SUB:
753
                    sign = (exp12[0].optionbits >> 1 & 1) ^ 1;
754
                    if (op == '-') sign ^= 1;
755
                    break;
756
                case II_ADD_ADD:
757
                    sign = exp12[0].optionbits >> 2 & 1;
758
                    if (op == '-') sign ^= 1;
759
                    break;
760
                default:   // no other instructions can be combined with + or -
761
                    expr.etype |= XPR_ERROR; expr.value.u = ERR_WRONG_OPERANDS;
762
                    return expr;
763
                }
764
                if (exp12[1].instruction == II_SUB) sign ^= 1;
765
 
766
                // add immediates and store them in exp12[1]
767
                if (sign) {
768
                    if (isfloat[1]) exp12[1].value.d -= exp12[0].value.d;
769
                    else exp12[1].value.i -= exp12[0].value.i;
770
                }
771
                else {
772
                    if (isfloat[1]) exp12[1].value.d += exp12[0].value.d;
773
                    else exp12[1].value.i += exp12[0].value.i;
774
                }
775
                exp12[0].value.i = 0;
776
                exp12[0].etype &= ~ (XPR_INT | XPR_FLT);
777
                if (exp12[0].instruction == II_ADD_ADD) {
778
                    exp12[0].instruction = II_ADD;
779
                    exp12[0].optionbits &= ~ 4;
780
                }
781
                else {
782
                    exp12[0].instruction = 0;
783
                }
784
            }
785
            else if (op == '*' && exp12[0].instruction == II_MUL) {
786
                if (isfloat[0]) {
787
                    exp12[1].value.d *= exp12[0].value.d;
788
                }
789
                else {
790
                    exp12[1].value.i *= exp12[0].value.i;
791
                }
792
                exp12[0].value.i = 0;
793
                exp12[0].etype &= ~ (XPR_INT | XPR_FLT | XPR_OP);
794
                exp12[0].instruction = 0;
795
            } /*
796
            else if (op == '&' && exp12[0].instruction == II_AND && !isfloat[0]) {
797
                exp12[1].value.i &= exp12[0].value.i;
798
                exp12[0].value.i = 0;
799
                exp12[0].etype &= ~ XPR_INT;
800
                exp12[0].instruction = 0;
801
            }
802
            else if (op == '|' && exp12[0].instruction == II_OR && !isfloat[0]) {
803
                exp12[1].value.i |= exp12[0].value.i;
804
                exp12[0].value.i = 0;
805
                exp12[0].etype &= ~ XPR_INT;
806
                exp12[0].instruction = 0;
807
            }
808
            else if (op == '^' && exp12[0].instruction == II_XOR && !isfloat[0]) {
809
                exp12[1].value.i ^= exp12[0].value.i;
810
                exp12[0].value.i = 0;
811
                exp12[0].etype &= ~ XPR_INT;
812
                exp12[0].instruction = 0;
813
            } */
814
            else {
815
                expr.etype |= XPR_ERROR; expr.value.u = ERR_WRONG_OPERANDS;
816
            }
817
        }
818
 
819
        // error if two memory operands 
820
        uint32_t etyp0 = exp12[0].etype, etyp1 = exp12[1].etype;
821
        //if ((etyp0 &  etyp1 & XPR_MEM) || (exp12[0].value.i && exp12[1].value.i)) {
822
        if (etyp0 & etyp1 & XPR_MEM) {
823
            expr.etype |= XPR_ERROR; expr.value.u = ERR_WRONG_OPERANDS;
824
            return expr;
825
        }
826
 
827
        // error if too many operands
828
        if (((etyp0 & XPR_REG1) != 0) + ((etyp0 & XPR_REG2) != 0) + ((etyp0 & XPR_REG3) != 0)
829
            + ((etyp1 & XPR_REG1) != 0) + ((etyp1 & XPR_REG2) != 0) + ((etyp1 & XPR_REG3) != 0)
830
            + (((etyp0 | etyp1) & XPR_MEM) != 0) + (((etyp0 | etyp1) & XPR_IMMEDIATE) != 0) > 3) {
831
            expr.etype |= XPR_ERROR; expr.value.u = ERR_TOO_MANY_OPERANDS;
832
            return expr;
833
        }
834
 
835
        // check which operations can swap
836
        if (op != '+' && op != '*' && op != '&' && op != '|' && op != '^' && op != '-') {
837
            cannotSwap = true;  // operation is not commutative ('-' is handled with sign bits)
838
        }
839
 
840
        // put operands in this order: register, memory, immediate
841
        if ((exp12[0].etype & (XPR_IMMEDIATE | XPR_MEM)) && !(exp12[1].etype & XPR_IMMEDIATE) && !cannotSwap) {
842
            // first operand is immediate or memory, and second operant is not immediate
843
            // swap operands if not two vector registers
844
            if (exp12[0].reg1 & exp12[1].reg1 & REG_V) {
845
                // both operands contain a vector register. cannot swap. make error message later if swapping required
846
                cannotSwap = true;
847
            }
848
            else if ((exp12[1].etype & XPR_MEM) && op == '*') {
849
                // second operand also contains memory
850
                cannotSwap = true;
851
            }
852
            else {  // swap operands to get immediate or memory operand last
853
                expr = exp12[0];  exp12[0] = exp12[1];  exp12[1] = expr;
854
                if (op == '-') {
855
                    op = '+';  // convert '-' to '+' and flip sign bit to make operation commutative
856
                    exp12[0].optionbits ^= 1;
857
                }
858
                swapped = true;
859
            }
860
        }
861
 
862
        if (op == '+' || op == '-') {
863
            /* done above:
864
            if (exp12[0].etype & (XPR_IMMEDIATE | XPR_MEM) && exp12[1].instruction == II_MUL && !(exp12[1].etype & (XPR_INT | XPR_FLT))) {
865
                // (memory or constant) + reg*reg. swap operands
866
                expr = exp12[0];  exp12[0] = exp12[1];  exp12[1] = expr;
867
                if (op == '-') {
868
                    exp12[0].optionbits ^= 1;  // invert signs in both operands
869
                    exp12[1].optionbits ^= 1;
870
                }
871
            } */
872
            if (!((exp12[0].etype | exp12[1].etype) & XPR_OP)) {
873
                // +/-R1 +/-R2
874
                if (op == '-') exp12[1].optionbits ^= 1;   // sign of second operand
875
                // change sign of constant if this simplifies it
876
                if ((exp12[1].etype & XPR_INT) && (exp12[1].optionbits & 1)) {
877
                    exp12[1].value.i = -exp12[1].value.i;
878
                    exp12[1].optionbits = 0;
879
                }
880
                else if ((exp12[1].etype & XPR_FLT) && (exp12[1].optionbits & 1)) {
881
                    exp12[1].value.d = -exp12[1].value.d;
882
                    exp12[1].optionbits = 0;
883
                }
884
                uint8_t s = exp12[0].optionbits | exp12[1].optionbits << 1;  // combine signs
885
                expr = exp12[1];  expr.tokens = numtokens;
886
                expr.reg1 = exp12[0].reg1;
887
                if (exp12[1].etype & XPR_REG1) {
888
                    expr.reg2 = exp12[1].reg1;  expr.etype |= XPR_REG2;
889
                }
890
                expr.etype |= XPR_OP | XPR_REG1;
891
                expr.optionbits = 0;
892
                switch (s) {
893
                case 0:  // R1 + R2
894
                    expr.instruction = II_ADD;  break;
895
                case 1:  // -R1 + R2
896
                    expr.instruction = II_SUB_REV;  break;
897
                case 2:  // R1 - R2
898
                    expr.instruction = II_SUB;  break;
899
                case 3:  // -R1 -R2
900
                    expr.instruction = II_ADD_ADD;
901
                    expr.value.i = 0;
902
                    expr.optionbits = s;
903
                    expr.etype |= XPR_INT | XPR_OPTIONS;
904
                    break;
905
                }
906
                return expr;
907
            }
908
            else if (exp12[0].instruction == II_MUL || exp12[1].instruction == II_MUL) {
909
                // (A*B)+C
910
                if (op == '-') exp12[1].optionbits ^= 1;  // change sign if '-'
911
                if (exp12[1].instruction == II_MUL) {     // swap expressions if A+(B*C)
912
                    if (exp12[0].reg1 & REG_V) {
913
                        expr.etype |= XPR_ERROR;
914
                        expr.value.w = ERR_CANNOT_SWAP_VECT; // cannot put vector addend as first operand
915
                        return expr;
916
                    }
917
                    expr = exp12[0]; exp12[0] = exp12[1]; exp12[1] = expr; // swap expressions
918
                }
919
                expr = exp12[0] | exp12[1];  // combine expressions
920
                expr.tokens = numtokens;
921
                if ((exp12[0].etype & exp12[1].etype & (XPR_MEM|XPR_IMMEDIATE)) || // two memory or two immediate operands
922
                ((exp12[0].etype & (XPR_MEM|XPR_IMMEDIATE)) == (XPR_MEM|XPR_IMMEDIATE))) { // exp12[0] has both memory and immediate
923
                    expr.etype |= XPR_ERROR;
924
                    expr.value.w = ERR_TOO_COMPLEX;
925
                    return expr;
926
                }
927
                expr.instruction = II_MUL_ADD;
928
                expr.etype |= XPR_OPTIONS;
929
                if (((exp12[0].etype & XPR_MEM) && !(exp12[1].etype & XPR_IMMEDIATE)) || (exp12[0].etype & XPR_IMMEDIATE)) {
930
                    expr.instruction = II_MUL_ADD2;   // get A*C+B
931
                    // we don't need to do anything with signs here because the sign options apply to product and addend, not to specific operands
932
                }
933
                expr.etype |= XPR_OP;
934
                expr.reg1 = exp12[0].reg1;  expr.reg2 = exp12[0].reg2;
935
                if (exp12[1].etype & XPR_REG) {  // C has a register
936
                    if (exp12[0].etype & XPR_REG2) {  // 3 registers
937
                        expr.reg3 = exp12[1].reg1;
938
                        expr.etype |= XPR_REG3;
939
                    }
940
                    else {
941
                        expr.reg2 = exp12[1].reg1;    // 2 registers
942
                        expr.etype |= XPR_REG2;
943
                    }
944
                }
945
                // optionbits 0-1 = sign of product. optionbits 2-3 = sign of addend. 
946
                expr.optionbits = 3 * (exp12[0].optionbits & 1) | 0xC * (exp12[1].optionbits & 1);
947
                expr.etype |= XPR_OPTIONS;
948
                return expr;
949
            }
950
            else if (exp12[0].instruction == II_ADD || exp12[0].instruction == II_SUB) {
951
                // (A+B)+C
952
                expr = exp12[0] | exp12[1];  // combine expressions 
953
                expr.tokens = numtokens;
954
                expr.reg1 = exp12[0].reg1;
955
                expr.etype |= XPR_OP;
956
                expr.instruction = II_ADD_ADD;
957
 
958
                if ((exp12[0].etype & XPR_IMMEDIATE) || ((exp12[0].etype & XPR_MEM) && !(exp12[1].etype & XPR_IMMEDIATE))) {
959
                    // does not fit
960
                    expr.etype |= XPR_ERROR;
961
                    expr.value.w = cannotSwap ? ERR_CANNOT_SWAP_VECT : ERR_TOO_COMPLEX;
962
                    return expr;
963
                }
964
 
965
                if (exp12[1].etype & XPR_REG) {  // C has a register
966
                    if (exp12[0].etype & XPR_REG2) {  // 3 registers
967
                        expr.reg3 = exp12[1].reg1;
968
                        expr.etype |= XPR_REG3;
969
                    }
970
                    else if (exp12[0].etype & XPR_REG1) {  // 2 registers
971
                        expr.reg2 = exp12[1].reg1;
972
                        expr.etype |= XPR_REG2;
973
                    }
974
                    else {
975
                        expr.reg1 = exp12[1].reg1;    // 1 registers
976
                        expr.etype |= XPR_REG1;
977
                    }
978
                }
979
                expr.optionbits = (exp12[0].optionbits & 3) | ((exp12[1].optionbits & 1) ^ (op == '-')) << 2;
980
                if (exp12[0].instruction == II_SUB) expr.optionbits ^= 2;
981
                if (swapped && op == '-') expr.optionbits ^= 7;
982
                expr.etype |= XPR_OPTIONS;
983
                return expr;
984
 
985
            }
986
            else if (exp12[1].instruction == II_ADD || exp12[1].instruction == II_SUB) {
987
                // A+(B+C)
988
                expr = exp12[0] | exp12[1];  // combine expressions 
989
                expr.tokens = numtokens;
990
                expr.reg1 = exp12[0].reg1;
991
                expr.etype |= XPR_OP;
992
                expr.instruction = II_ADD_ADD;
993
 
994
                if (exp12[0].etype & exp12[1].etype & (XPR_IMMEDIATE | XPR_MEM)) {
995
                    // does not fit
996
                    expr.etype |= XPR_ERROR;
997
                    expr.value.w = ERR_TOO_COMPLEX;
998
                    return expr;
999
                }
1000
 
1001
                if (exp12[0].etype & XPR_MEM) {
1002
                    // A = mem, B = register, C = immediate. Needs additional reordering
1003
                    expr.optionbits = ((exp12[1].optionbits & 1) ^ (op == '-'))   // register into first place
1004
                        | (exp12[0].optionbits & 1) << 1                          // memory in second place
1005
                        | ((exp12[1].optionbits >> 1 & 1) ^ (op == '-')) << 2;     // immediate in third place
1006
                    if (exp12[1].instruction == II_SUB) expr.optionbits ^= 4;
1007
                    if (swapped && op == '-') expr.optionbits ^= 7;
1008
                    expr.reg1 = exp12[1].reg1;
1009
                    expr.etype |= XPR_OPTIONS;
1010
                    return expr;
1011
                }
1012
 
1013
 
1014
                if (exp12[1].etype & XPR_REG2) {
1015
                    // 3 registers
1016
                    expr.reg2 = exp12[1].reg1;
1017
                    expr.reg3 = exp12[1].reg2;
1018
                    expr.etype |= XPR_REG2 | XPR_REG3;
1019
                }
1020
                else if (exp12[1].etype & XPR_REG1) {
1021
                    // 2 registers
1022
                    expr.reg2 = exp12[1].reg1;
1023
                    expr.etype |= XPR_REG2;
1024
                }
1025
 
1026
                expr.optionbits = (exp12[0].optionbits & 1) | 6 * ((exp12[1].optionbits & 1) ^ (op == '-'));
1027
                if (exp12[1].instruction == II_SUB) expr.optionbits ^= 4;
1028
                if (swapped && op == '-') expr.optionbits ^= 7;
1029
                expr.etype |= XPR_OPTIONS;
1030
                return expr;
1031
            }
1032
        }
1033
        else if (!((exp12[0].etype | exp12[1].etype) & XPR_OP)
1034
            && (op == '*' || (op == '/' && !swapped))) {
1035
            // (+/- a) * (+/- b)
1036
            expr = exp12[0] | exp12[1];
1037
            expr.etype |= XPR_OP;
1038
            expr.tokens = numtokens;
1039
            expr.optionbits = exp12[0].optionbits ^ exp12[1].optionbits;
1040
            if (expr.optionbits & 1) {   // change sign
1041
                if ((exp12[1].etype & 0xF) == XPR_FLT) {
1042
                    expr.value.d = -exp12[1].value.d;
1043
                    expr.optionbits = 0;
1044
                }
1045
                else if ((exp12[1].etype & 0xF) == XPR_INT) {
1046
                    expr.value.i = -exp12[1].value.i;
1047
                    expr.optionbits = 0;
1048
                }
1049
                else if (/*(exp12[1].etype & XPR_REG) &&*/ op == '*' && expr.value.i == 0) {
1050
                    // change -a*b to -a*b + 0
1051
                    expr.instruction = II_MUL_ADD;
1052
                    expr.optionbits = 0x3;
1053
                    expr.reg1 = exp12[0].reg1;
1054
                    if (exp12[1].etype & XPR_REG1) {
1055
                        expr.reg2 = exp12[1].reg1;  expr.etype |= XPR_REG2;
1056
                    }
1057
                    expr.etype |= XPR_INT | XPR_OPTIONS;
1058
                    return expr;
1059
                }
1060
                else {
1061
                    expr.etype |= XPR_ERROR; expr.value.w = ERR_TOO_COMPLEX;
1062
                    return expr;
1063
                }
1064
            }
1065
            expr.reg1 = exp12[0].reg1;
1066
            if (exp12[1].etype & XPR_REG1) {
1067
                expr.reg2 = exp12[1].reg1;  expr.etype |= XPR_REG2;
1068
            }
1069
            expr.instruction = (op == '*') ? II_MUL : II_DIV;
1070
            return expr;
1071
        }
1072
 
1073
        else if (((exp12[0].etype & exp12[1].etype) & XPR_INT)
1074
        && (op == '='+D2 || op == '!'+EQ)
1075
        && exp12[0].value.i == exp12[1].value.i
1076
        && ((exp12[0].etype | exp12[1].etype) & (XPR_REG1 | XPR_REG2)) == XPR_REG1
1077
        && (exp12[0].etype & exp12[1].etype & XPR_REG1) == 0) {
1078
            // (r1 & const) == const gives test_bits_and
1079
            expr = exp12[0] | exp12[1];
1080
            expr.etype |= XPR_OP | XPR_OPTIONS;
1081
            expr.tokens = numtokens;
1082
            expr.instruction = II_TEST_BITS_AND;
1083
            if (op == '!'+EQ) expr.optionbits ^= 1;
1084
            return expr;
1085
        }
1086
        else if (op == '&'+D2 || op == '|'+D2 || op == '^' || op == '^'+D2) {
1087
            // possible combination of compare or test with extra boolean operand
1088
            int swap = exp12[1].instruction != 0;
1089
            expr = exp12[swap];
1090
            if (expr.instruction == II_COMPARE && exp12[1-swap].etype == (XPR_REG | XPR_REG1)) {
1091
                // use fallback register as an extra boolean operand on compare instruction
1092
                switch (op & 0xFF) {
1093
                case '&':
1094
                    expr.optionbits |= 0x10;  break;
1095
                case '|':
1096
                    expr.optionbits |= 0x20;  break;
1097
                case '^':
1098
                    expr.optionbits |= 0x30;  break;
1099
                default:
1100
                    expr.etype |= XPR_ERROR; expr.value.u = ERR_TOO_COMPLEX;
1101
                }
1102
                expr.etype |= XPR_OP | XPR_OPTIONS | XPR_FALLBACK;
1103
                expr.tokens = numtokens;
1104
                expr.fallback = exp12[1-swap].reg1;
1105
                return expr;
1106
            }
1107
            /*else if (expr.instruction >= II_TEST_BIT && expr.instruction <= II_TEST_BITS_OR && exp12[1-swap].etype == (XPR_REG | XPR_REG1)) {
1108
                // Use fallback register as an extra boolean operand on bit test instructions
1109
                // This does not work yet. test_bit cannot be expressed with high level operators
1110
                switch (op & 0xFF) {
1111
                case '&':
1112
                    expr.optionbits |= 0x01;  break;
1113
                case '|':
1114
                    expr.optionbits |= 0x02;  break;
1115
                case '^':
1116
                    expr.optionbits |= 0x03;  break;
1117
                default:
1118
                    expr.etype |= XPR_ERROR; expr.value.u = ERR_TOO_COMPLEX;
1119
                }
1120
                expr.etype |= XPR_OP | XPR_OPTIONS | XPR_FALLBACK;
1121
                expr.tokens = numtokens;
1122
                expr.fallback = exp12[1-swap].reg1;
1123
                return expr;
1124
            }*/
1125
        }
1126
    }
1127
 
1128
    // not a complex expression
1129
    if ((ex1.etype & (XPR_IMMEDIATE | XPR_MEM)) && !((ex1.reg1 & REG_V) || (ex2.etype & XPR_IMMEDIATE))){
1130
        // first operand is integer, float or memory. swap operands if not two vector registers or memory and immediate
1131
        exp12[0] = ex2;  exp12[1] = ex1;  swapped = true;
1132
    }
1133
    else {
1134
        exp12[0] = ex1;  exp12[1] = ex2;
1135
    }
1136
    expr.etype |= (exp12[1].etype & XPR_REG1) << 1;  // XPR_REG1 becomes XPR_REG2
1137
 
1138
    // combine everything from the two operands
1139
    expr = exp12[0] | exp12[1];
1140
    expr.etype |= XPR_OP;
1141
    expr.tokens = numtokens;
1142
    expr.reg1 = exp12[0].reg1;
1143
    expr.reg2 = exp12[1].reg1;
1144
    expr.etype |= (exp12[1].etype & XPR_REG1) << 1;
1145
 
1146
    if (expr.instruction) {
1147
        expr.etype |= XPR_ERROR; expr.value.u = ERR_TOO_COMPLEX;
1148
        return expr;
1149
    }
1150
    // 2-operand instruction
1151
    switch (op) {
1152
    case '+':
1153
        expr.instruction = II_ADD;  break;
1154
    case '-':
1155
        expr.instruction = swapped ? II_SUB_REV : II_SUB;  break;
1156
    case '*':
1157
        expr.instruction = II_MUL;  break;
1158
    case '/':
1159
        expr.instruction = swapped ? II_DIV_REV : II_DIV;  break;
1160
    case '%':
1161
        if (swapped) {expr.etype |= XPR_ERROR; expr.value.u = ERR_WRONG_TYPE;}
1162
        expr.instruction = II_REM;  break;
1163
    case '&':  case '&'+D2:  // boolean AND and bitwise AND have same implementation
1164
        expr.instruction = II_AND;  break;
1165
    case '|':  case '|'+D2:  // boolean OR and bitwise OR have same implementation
1166
        expr.instruction = II_OR;  break;
1167
    case '^':  case '^'+D2:
1168
        expr.instruction = II_XOR;  break;
1169
    case '<':
1170
        expr.instruction = II_COMPARE;
1171
        expr.optionbits = 2 ^ swapped;
1172
        expr.etype |= XPR_OPTIONS;
1173
        break;
1174
    case '<' + EQ:    // <=
1175
        expr.instruction = II_COMPARE;
1176
        expr.optionbits = 5 ^ swapped;
1177
        expr.etype |= XPR_OPTIONS;
1178
        break;
1179
    case '>':
1180
        expr.instruction = II_COMPARE;
1181
        expr.optionbits = 4 ^ swapped;
1182
        expr.etype |= XPR_OPTIONS;
1183
        break;
1184
    case '>' + EQ:   // >=
1185
        expr.instruction = II_COMPARE;
1186
        expr.optionbits = 3 ^ swapped;
1187
        expr.etype |= XPR_OPTIONS;
1188
        break;
1189
    case '='+D2:  // ==
1190
        expr.instruction = II_COMPARE;
1191
        expr.optionbits = 0;
1192
        //expr.etype |= XPR_OPTIONS;
1193
        break;
1194
    case '!'+EQ:  // !=
1195
        expr.instruction = II_COMPARE;
1196
        expr.etype |= XPR_OPTIONS;
1197
        expr.optionbits = 1;      // compare for not equal
1198
        if ((expr.reg1 & REG_V) && (dataType & TYP_FLOAT)) {
1199
            expr.optionbits |= 8; // floating point not equal includes unordered
1200
        }
1201
        break;
1202
    case '<' + D2:  // <<
1203
        if (swapped) {expr.etype |= XPR_ERROR; expr.value.u = ERR_WRONG_TYPE;}
1204
        expr.instruction = II_SHIFT_LEFT;  break;
1205
    case '>' + D2:   // >>
1206
        if (swapped) {expr.etype |= XPR_ERROR; expr.value.u = ERR_WRONG_TYPE;}
1207
        expr.instruction = II_SHIFT_RIGHT_S;  break;
1208
    case '>' + D3:   // >>>
1209
        if (swapped) {expr.etype |= XPR_ERROR; expr.value.u = ERR_WRONG_TYPE;}
1210
        expr.instruction = II_SHIFT_RIGHT_U;  break;
1211
    default:
1212
        expr.etype |= XPR_ERROR; expr.value.u = ERR_WRONG_TYPE;
1213
    }
1214
    return expr;
1215
}
1216
 
1217
 
1218
// Interpret dyadic expression generating memory operand. 
1219
// both expressions are inside [] or at least one contains components other than integer constants
1220
SExpression CAssembler::op2Memory(uint32_t op, SExpression & exp1, SExpression & exp2) {
1221
    SExpression expr;                                // return value
1222
    SExpression expt;    // temporary value
1223
    expr.tokens = exp1.tokens + exp2.tokens + 1;  // total number of tokens
1224
    uint64_t f;        // temporary factor
1225
    int32_t symi1 = 0, symi2 = 0;       // symbol indexes
1226
 
1227
    if (!((exp1.etype|exp2.etype) & (XPR_IMMEDIATE|XPR_BASE|XPR_INDEX|XPR_OPTION|XPR_SYM1|XPR_SYM2|XPR_LIMIT|XPR_LENGTH|XPR_BROADC))) {
1228
        // combination of only integer expressions inside []
1229
        // combine everything from the two operands
1230
        expr = exp1 | exp2;
1231
        expr.tokens = exp1.tokens + exp2.tokens + 1;
1232
        expr.etype &= ~XPR_OP;  expr.instruction = 0;  // operator is resolved here
1233
        switch (op) {
1234
        case '+':  // adding offsets
1235
            expr.offset_mem = exp1.offset_mem + exp2.offset_mem;
1236
            break;
1237
        case '-':  // 
1238
            expr.offset_mem = exp1.offset_mem - exp2.offset_mem;
1239
            break;
1240
        case '*':
1241
            expr.offset_mem = exp1.offset_mem * exp2.offset_mem;
1242
            break;
1243
        case '/':
1244
            if (exp2.offset_mem == 0) {
1245
                expr.etype |= XPR_ERROR;
1246
                expr.value.u = ERR_OVERFLOW;
1247
                break;
1248
            }
1249
            expr.offset_mem = exp1.offset_mem / exp2.offset_mem;
1250
            break;
1251
        case '<' + D2:  // <<
1252
            expr.offset_mem = exp1.offset_mem << exp2.offset_mem;
1253
            break;
1254
        case '>' + D2:  // >>  shift right signed
1255
             expr.offset_mem = exp1.offset_mem >> exp2.offset_mem; // signed shift right
1256
            break;
1257
        case '>' + D3:  // >>> unsigned shift right
1258
            expr.offset_mem = uint32_t(exp1.offset_mem) >> uint32_t(exp2.offset_mem); // unsigned shift right
1259
            break;
1260
        default:  // wrong operator
1261
            expr.value.u = ERR_WRONG_TYPE;
1262
            expr.etype |= XPR_ERROR;  return expr;
1263
        }
1264
        return expr;
1265
    }
1266
 
1267
    // not only integer expressions
1268
    if ((exp2.etype & XPR_SYM1) && op == '-') {
1269
        // subtracting two symbol addresses
1270
        if (exp1.sym1) {
1271
            exp2.sym2 = exp2.sym1;  exp2.sym1 = 0;
1272
            exp2.etype = (exp2.etype & ~XPR_SYM1) | XPR_SYM2;
1273
            if (exp1.symscale1 == 0) exp1.symscale1 = 1;
1274
            if (exp2.symscale1 == 0) exp2.symscale1 = 1;
1275
            if (exp1.symscale1 != exp2.symscale1 || exp2.sym2 == 0) {
1276
                exp1.value.u = ERR_CONFLICT_TYPE;  // conflicting scale factors
1277
                exp1.etype |= XPR_ERROR;  return exp1;
1278
            }
1279
        }
1280
        else if (exp1.sym3) {
1281
            exp2.sym4 = exp2.sym3;  exp2.sym3 = 0;
1282
            exp2.etype = (exp2.etype & ~XPR_SYM1) | XPR_SYM2;
1283
            if (exp1.symscale3 == 0) exp1.symscale3 = 1;
1284
            if (exp2.symscale3 == 0) exp2.symscale3 = 1;
1285
            if (exp1.symscale3 != exp2.symscale3 || exp2.sym4 == 0) {
1286
                exp1.value.u = ERR_CONFLICT_TYPE;  // conflicting scale factors
1287
                exp1.etype |= XPR_ERROR;  return exp1;
1288
            }
1289
        }
1290
        else {
1291
            exp1.value.u = ERR_CONFLICT_TYPE;  // conflicting scale factors
1292
            exp1.etype |= XPR_ERROR;  return exp1;
1293
        }
1294
    }
1295
    // error checks
1296
    if (exp1.etype & exp2.etype & (XPR_SYM1 | XPR_SYM2 | XPR_SYMSCALE | XPR_INDEX
1297
        | XPR_LIMIT | XPR_LENGTH | XPR_BROADC)) {
1298
        exp1.value.u = ERR_MEM_COMPONENT_TWICE;              // some component or option specified twice
1299
        exp1.etype |= XPR_ERROR;  return exp1;
1300
    }
1301
    if (((exp1.etype | exp2.etype) & (XPR_LIMIT | XPR_OFFSET)) == (XPR_LIMIT | XPR_OFFSET)) {
1302
        exp1.value.u = ERR_LIMIT_AND_OFFSET;  // cannot have both offset and limit
1303
        exp1.etype |= XPR_ERROR;  return exp1;
1304
    }
1305
 
1306
    if ((exp2.etype & XPR_BASE) && ((exp1.etype & XPR_BASE) || op == '-')) {
1307
        // adding two registers or subtracting a register. make the second an index register
1308
        if (exp2.base == 31 && (exp1.etype & XPR_BASE) && !(exp2.etype & XPR_INDEX)) {
1309
            // stack pointer cannot be index. make first register an index instead
1310
            exp1.index = exp1.base; exp1.base = 0;
1311
            exp1.etype = (exp1.etype & ~XPR_BASE) | XPR_INDEX;
1312
            exp1.scale = 1;
1313
        }
1314
        else {
1315
            exp2.index = exp2.base; exp2.base = 0;
1316
            exp2.etype = (exp2.etype & ~XPR_BASE) | XPR_INDEX;
1317
            exp2.scale = 1;
1318
        }
1319
    }
1320
    // combine everything from the two operands
1321
    expr = exp1 | exp2;
1322
    expr.tokens = exp1.tokens + exp2.tokens + 1;
1323
    expr.value.u = exp1.value.u + exp2.value.u;  // add values, except for special cases below
1324
    expr.offset_mem = exp1.offset_mem + exp2.offset_mem;        // add offsets, except for special cases below
1325
    expr.offset_jump = exp1.offset_jump + exp2.offset_jump;     // add jump offsets
1326
    expr.etype &= ~XPR_OP;  expr.instruction = 0;  // operator is resolved here
1327
 
1328
    switch (op) {
1329
    case '+':  // adding components. offsets have been added above
1330
        /* Changed: immediate value outside [] cannot be converted to offset:
1331
        if ((expr.etype & (XPR_REG | XPR_BASE | XPR_SYM1)) && (expr.etype & XPR_INT) && (expr.etype & XPR_MEM)) {
1332
            // adding offset. convert value to offset
1333
            expr.offset += expr.value.i;
1334
            expr.value.i = 0;
1335
            expr.etype = (expr.etype | XPR_OFFSET) & ~XPR_IMMEDIATE;
1336
        } */
1337
        break;
1338
    case ',':  // combining components. components are combined below
1339
        if (exp1.value.u && exp2.value.u) {
1340
            expr.value.u = ERR_WRONG_TYPE;       // cannot combine integer offsets with comma operator
1341
            expr.etype |= XPR_ERROR;  return expr;
1342
        }
1343
        if ((expr.etype & XPR_INDEX) && (expr.etype & (XPR_LENGTH | XPR_BROADC))) { // both index and broadcast
1344
            if (expr.scale == -1) {
1345
                if (expr.index != expr.length) { // scale = -1. index and length must be the same
1346
                    expr.value.u = ERR_NEG_INDEX_LENGTH;
1347
                    expr.etype |= XPR_ERROR;  return expr;
1348
                }
1349
            }
1350
            else { // cannot have index and length/broadcast
1351
                expr.value.u = ERR_INDEX_AND_LENGTH;
1352
                expr.etype |= XPR_ERROR;  return expr;
1353
            }
1354
        }
1355
        break;
1356
    case '-':  // subtract offsets or registers (symbol addresses subtracted above)
1357
        /* Changed: immediate value outside [] cannot be converted to offset:
1358
        if ((exp1.etype & (XPR_REG | XPR_BASE | XPR_SYM1)) && (exp2.etype & XPR_INT) && (expr.etype & XPR_MEM)) {
1359
            // subtracting offset. convert value to offset
1360
            expr.offset = exp1.offset - exp2.value.i;
1361
            expr.value.i = 0;
1362
            expr.etype = (expr.etype | XPR_OFFSET) & ~XPR_IMMEDIATE;
1363
        }
1364
        else  */
1365
        {
1366
        expr.offset_mem = exp1.offset_mem - exp2.offset_mem;
1367
        expr.offset_jump = exp1.offset_jump - exp2.offset_jump;
1368
        expr.value.u = exp1.value.u - exp2.value.u;
1369
        }
1370
        if (exp2.etype & XPR_INDEX) {  // subtracting a register gives negative index
1371
            expr.scale = - exp2.scale;
1372
        }
1373
        else if ((exp1.etype & XPR_SYM1) && (exp2.etype & XPR_SYM2)) {
1374
            // subtracting two symbols. has been fixed above
1375
            // check if symbols are in the same domain
1376
            if (exp1.sym1) {
1377
                symi1 = findSymbol(exp1.sym1);
1378
                symi2 = findSymbol(exp2.sym2);
1379
            }
1380
            else if (exp1.sym3) {
1381
                symi1 = findSymbol(exp1.sym3);
1382
                symi2 = findSymbol(exp2.sym4);
1383
            }
1384
            if (symi1 > 0 && symi2 > 0
1385
                && (symbols[symi1].st_other & symbols[symi2].st_other & (SHF_IP | SHF_DATAP | SHF_THREADP)) == 0
1386
                && (symbols[symi1].st_type & symbols[symi2].st_type & STT_CONSTANT) == 0) {
1387
                errors.reportLine(ERR_RELOCATION_DOMAIN);
1388
            }
1389
        }
1390
        //else if ((expr.etype & XPR_IMMEDIATE) == XPR_INT) expr.etype |= XPR_OFFSET;  // value is offset
1391
        if (exp2.etype & (XPR_SYM1|XPR_SYMSCALE)) {
1392
            expr.value.u = ERR_WRONG_TYPE;    // cannot subtract these components
1393
            expr.etype |= XPR_ERROR;  return expr;
1394
        }
1395
        break;
1396
    case '<'+D2:  // index << s = index * (1 << s)
1397
        //exp2.value.u = (uint64_t)1 << exp2.value.u; 
1398
        exp2.offset_mem = 1 << exp2.offset_mem;
1399
        goto MULTIPLYINDEX; // continue in case '*'
1400
    case '*':  // indexregister * scale
1401
        if ((exp1.etype & (XPR_INT|XPR_OFFSET)) && (exp2.etype & (XPR_BASE|XPR_INDEX))){
1402
            // first operand is integer, second operand is register. swap operands
1403
            expt = exp2;  exp2 = exp1;  exp1 = expt;
1404
        }
1405
        MULTIPLYINDEX:
1406
        if ((exp1.etype & XPR_BASE) && !(exp1.etype & XPR_INDEX)) {  // convert base to index
1407
            exp1.index = exp1.base;  exp1.base = 0;  exp1.scale = 1;
1408
            exp1.etype = (exp1.etype & ~XPR_BASE) | XPR_INDEX;
1409
        }
1410
        if (exp2.etype & XPR_INT) {  // convert integer to offset. should not occur
1411
            exp2.offset_mem = exp2.value.w; exp2.value.i = 0;
1412
            exp2.etype = (exp2.etype & ~XPR_INT) | XPR_OFFSET;
1413
        }
1414
        if (!(exp1.etype & XPR_INDEX) || !(exp2.etype & XPR_OFFSET)
1415
            || ((exp1.etype | exp2.etype) & (XPR_OPTION|XPR_SYM1|XPR_SYM2|XPR_LIMIT|XPR_LENGTH|XPR_BROADC))) {
1416
            expr.value.u = ERR_WRONG_TYPE;    // cannot multiply anything else
1417
            expr.etype |= XPR_ERROR;  return expr;
1418
        }
1419
        f = int64_t(exp2.offset_mem) * exp1.scale;
1420
        if ((f & (f - 1)) || f == 0 || f > 16) {  // check that scale is a power of 2, not bigger than 16
1421
            expr.value.u = ERR_SCALE_FACTOR;    // wrong scale factor
1422
            expr.etype |= XPR_ERROR;  return expr;
1423
        }
1424
        expr.base = exp1.base;  expr.index = exp1.index;
1425
        expr.scale = (int8_t)f;
1426
        expr.etype = exp1.etype | (exp2.etype & ~(XPR_INT|XPR_OFFSET));
1427
        expr.value.u = 0;
1428
        expr.offset_mem = exp1.offset_mem;
1429
        break;
1430
    case '>'+D2:  // divide (sym1-sym2) >> s = (sym1-sym2) / (1 << s)
1431
        exp2.value.u = (uint64_t)1 << exp2.value.u;
1432
        exp2.offset_mem = (uint64_t)1 << exp2.offset_mem;
1433
        // continue in case '/'
1434
    case '/':  // divide (sym1-sym2) / scale
1435
        if ((exp2.etype & XPR_OFFSET) && !(exp2.etype & (XPR_REG | XPR_INT | XPR_BASE))) {
1436
            // constant has been interpreted as offset because it is inside []. change it to XPR_INT
1437
            exp2.value.i = exp2.offset_mem; exp2.offset_mem = 0;
1438
            exp2.etype = (exp2.etype & ~(XPR_OFFSET)) | XPR_INT;
1439
            expr.offset_mem = exp1.offset_mem;
1440
        }
1441
        if (!(exp1.etype & XPR_SYM1) || ((exp2.etype & 0xF) != XPR_INT)
1442
            || ((exp1.etype | exp2.etype) & (XPR_REG|XPR_OPTION|XPR_LIMIT|XPR_LENGTH|XPR_BROADC))) {
1443
            expr.value.u = ERR_WRONG_TYPE;    // cannot divide anything else
1444
            expr.etype |= XPR_ERROR;  return expr;
1445
        }
1446
        f = exp2.value.u;
1447
        if (exp1.symscale1) f *= exp1.symscale1;
1448
        if ((f & (f - 1)) || f == 0 || f > 16) {  // check that scale is a power of 2, not bigger than 16
1449
            expr.value.u = ERR_SCALE_FACTOR;    // wrong scale factor
1450
            expr.etype |= XPR_ERROR;  return expr;
1451
        }
1452
        expr.symscale1 = (int8_t)f;
1453
        expr.etype |= XPR_SYMSCALE;
1454
        expr.etype = exp1.etype | (exp2.etype & ~XPR_INT);
1455
        expr.value.u = exp1.value.u;
1456
        break;
1457
    case '=':  // option = value
1458
        // check if operands contain anything else
1459
        if (!(exp1.etype & XPR_OPTION) || !(exp2.etype & (XPR_INT | XPR_BASE | XPR_REG))
1460
            || ((exp1.etype | exp2.etype) & (XPR_SYM1|XPR_SYM2|XPR_REG2|XPR_INDEX|XPR_LIMIT|XPR_LENGTH|XPR_BROADC))) {
1461
            expr.value.u = ERR_WRONG_TYPE;    // cannot uses '=' on anyting else inside []
1462
            expr.etype |= XPR_ERROR;  return expr;
1463
        }
1464
        switch (exp1.value.w) {
1465
        case OPT_LENGTH:  // length = register
1466
            if ((exp2.etype & XPR_REG1) && (exp2.reg1 & REG_R)) {
1467
                // length = register, outside []
1468
                expr.etype = XPR_LENGTH | XPR_MEM;
1469
                expr.length = exp2.reg1;
1470
                expr.base = 0;
1471
                expr.value.i = 0;
1472
                break;
1473
            }
1474
            // length = register, inside []
1475
            if (!(exp2.etype & XPR_BASE) || (exp2.base & 0xE0) != REG_R) {
1476
                expr.value.u = ERR_WRONG_TYPE;    // cannot uses '=' on anyting else inside []
1477
                expr.etype |= XPR_ERROR;  return expr;
1478
            }
1479
            expr.etype = XPR_LENGTH | XPR_MEM;
1480
            expr.length = exp2.base;
1481
            expr.base = 0;
1482
            expr.value.i = 0;
1483
            break;
1484
        case OPT_BROADCAST:  // broadcast = register
1485
            if (!(exp2.etype & XPR_BASE) || (exp2.base & 0xE0) != REG_R) {
1486
                expr.value.u = ERR_WRONG_TYPE;    // cannot uses '=' on anyting else inside []
1487
                expr.etype |= XPR_ERROR;  return expr;
1488
            }
1489
            expr.etype = XPR_BROADC | XPR_MEM;
1490
            expr.length = exp2.base;
1491
            expr.base = 0;
1492
            expr.value.i = 0;
1493
            break;
1494
        case OPT_LIMIT:   // limit = integer
1495
            if (!(exp2.etype & XPR_INT)) {
1496
                expr.value.u = ERR_WRONG_TYPE;    // cannot uses '=' on anyting else inside []
1497
                expr.etype |= XPR_ERROR;  return expr;
1498
            }
1499
            if (exp1.etype & XPR_OFFSET) {  // cannot have both limit and offset
1500
                expr.etype = ERR_LIMIT_AND_OFFSET;
1501
                expr.etype |= XPR_ERROR;  return expr;
1502
            }
1503
            expr.etype = XPR_LIMIT | XPR_MEM;
1504
            expr.value.u = exp2.value.u;
1505
            break;
1506
        case OPT_SCALAR:  // scalar
1507
            expr.etype = XPR_SCALAR | XPR_MEM;
1508
            expr.value.i = 0;
1509
            break;
1510
        case OPT_MASK:
1511
            if (!(exp2.etype & (XPR_REG | XPR_REG1))) {
1512
                expr.etype = ERR_MASK_NOT_REGISTER;
1513
                expr.etype |= XPR_ERROR;  return expr;
1514
            }
1515
            expr.etype = XPR_MASK;
1516
            expr.mask = exp2.reg1;
1517
            expr.reg1 = 0;
1518
            break;
1519
        case OPT_FALLBACK:
1520
            if (exp2.etype == (XPR_REG | XPR_REG1) && (exp2.reg1 & 0x1F) != 0x1F) {
1521
                expr.fallback = exp2.reg1;
1522
                expr.etype = XPR_FALLBACK;
1523
                expr.reg1 = 0;
1524
            }
1525
            else if ((exp2.etype & XPR_IMMEDIATE) && exp2.value.i == 0){
1526
                expr.fallback = (expr.mask & 0xF0) | 0x1F;
1527
                expr.etype = XPR_FALLBACK;
1528
            }
1529
            else {
1530
                expr.value.u = ERR_FALLBACK_WRONG;
1531
                expr.etype |= XPR_ERROR;  return expr;
1532
            }
1533
            break;
1534
        case OPT_OPTIONS:
1535
            if ((exp2.etype & 0xF) == XPR_INT) {
1536
                expr.etype = (expr.etype & ~XPR_IMMEDIATE) | XPR_OPTIONS;
1537
                expr.optionbits = (uint8_t)exp2.value.u;  // move value to optionbits
1538
                expr.value.i = 0;
1539
                return expr;
1540
            }
1541
            else {
1542
                expr.etype = ERR_WRONG_TYPE;
1543
                expr.etype |= XPR_ERROR;
1544
                return expr;
1545
            }
1546
            break;
1547
        default:  // mask and fallback options not allowed inside []
1548
            expr.value.u = ERR_NOT_INSIDE_MEM;  // change error message
1549
            expr.etype |= XPR_ERROR;  return expr;
1550
        }
1551
        break;
1552
 
1553
    default:  // wrong operator
1554
        expr.value.u = ERR_WRONG_TYPE;
1555
        expr.etype |= XPR_ERROR;  return expr;
1556
    }
1557
    if ((expr.etype & XPR_INT) && !(expr.etype & (XPR_SYM1 | XPR_INDEX))) {           // value not used otherwise is offset
1558
        expr.etype = (expr.etype & ~(XPR_INT)) | XPR_OFFSET;
1559
    }
1560
    return expr;
1561
}
1562
 
1563
 
1564
// Interpreted triadic expression exp1 ? exp2 : exp3 at the indicated positions
1565
SExpression CAssembler::op3(uint32_t tok1, uint32_t toklow, uint32_t tokcolon, uint32_t maxtok, uint32_t options) {
1566
    SExpression exp1, exp2;
1567
    uint32_t cond;   // evaluated condition
1568
 
1569
    exp1 = expression(tok1, toklow - tok1, options);  // evaluate expression before '?'
1570
    if (exp1.tokens != toklow - tok1) errors.report(tokens[tok1 + exp1.tokens]);
1571
 
1572
    if ((exp1.etype & XPR_REG) == 0 && (exp1.etype & (XPR_INT | XPR_FLT | XPR_STRING))) {
1573
        // condition is a constant. just choose one of the two operands
1574
 
1575
        if ((exp1.etype & 0xF) == XPR_FLT) cond = exp1.value.d != 0.; // evaluate condition to true or false
1576
        else if ((exp1.etype & 0xF) == XPR_STRING) {   // string is false if empty or "0"
1577
            cond = (exp1.sym2 != 0 && (exp1.sym2 > 1 || stringBuffer.get<uint16_t>((uint32_t)exp1.value.u) != '0'));
1578
        }
1579
        else cond = exp1.value.i != 0;
1580
 
1581
        // the expression that is not selected is evaluated with option = 0x10 to suppress errors but still count the tokens
1582
        exp1 = expression(toklow + 1, tokcolon - (toklow + 1), options | (cond ^ 1) << 4);   // evaluate first expression
1583
        if (exp1.tokens != tokcolon - (toklow + 1)) errors.report(tokens[toklow + 1 + exp1.tokens]);
1584
        exp2 = expression(tokcolon + 1, tok1 + maxtok - (tokcolon + 1), options | cond << 4);      // evaluate second expression
1585
 
1586
        // number of tokens
1587
        exp1.tokens = exp2.tokens = tokcolon - tok1 + 1 + exp2.tokens;
1588
 
1589
        // return the chosen expression
1590
        if (cond) return exp1; else return exp2;
1591
    }
1592
 
1593
    // condition is not a constant. It must be a mask register
1594
    if ((exp1.etype & XPR_REG) == 0 || exp1.reg1 == 0 || exp1.etype & (XPR_OP|XPR_OPTION|XPR_MEM|XPR_SYM1|XPR_MASK|XPR_UNRESOLV)) {
1595
        errors.report(tokens[tok1].pos, tokens[tok1].stringLength, ERR_MASK_NOT_REGISTER);
1596
    }
1597
    uint8_t maskreg = exp1.reg1;  // save mask register
1598
 
1599
    // evaluate the middle expression
1600
    exp1 = expression(toklow + 1, tokcolon - (toklow + 1), options);
1601
    if (exp1.tokens != tokcolon - (toklow + 1)) errors.report(tokens[toklow + 1 + exp1.tokens]);
1602
 
1603
    // third expression must be fallback
1604
    exp2 = expression(tokcolon + 1, tok1 + maxtok - (tokcolon + 1), options);
1605
    uint8_t fallbackreg = 0;  // fallback register
1606
    if (exp2.etype & XPR_REG) {
1607
        fallbackreg = exp2.reg1;
1608
        exp1.etype |= XPR_FALLBACK;
1609
    }
1610
    else if ((exp2.etype & (XPR_INT | XPR_FLT)) && exp2.value.i == 0) {
1611
        fallbackreg = maskreg | 0x1F;  // register 31 with same type as mask register    
1612
        exp1.etype |= XPR_FALLBACK;
1613
    }
1614
    if (exp2.etype & (XPR_STRING | XPR_OP | XPR_OPTION | XPR_MEM | XPR_SYM1 | XPR_MASK) || exp2.value.i) {
1615
        errors.report(tokens[tokcolon+1].pos, tokens[tokcolon+exp2.tokens+1].pos  - tokens[tokcolon+1].pos, ERR_FALLBACK_WRONG);
1616
    }
1617
    // insert mask and fallback in exp1
1618
    exp1.etype |= XPR_MASK;
1619
    exp1.mask = maskreg;
1620
    exp1.fallback = fallbackreg;
1621
    exp1.tokens = tokcolon - tok1 + 1 + exp2.tokens;
1622
    return exp1;
1623
}
1624
 
1625
 
1626
// Convert -(expression), e.g. -(A-B)
1627
SExpression CAssembler::op1minus(SExpression & exp1) {
1628
    exp1.tokens++;
1629
    if ((exp1.etype & (XPR_REG | XPR_MEM)) && !(exp1.etype & XPR_OP) && exp1.value.i == 0) {  // -reg or -mem
1630
        exp1.etype |= XPR_OP | XPR_INT;
1631
        exp1.instruction = II_SUB_REV;              // 0 - expression
1632
    }
1633
    else if (exp1.instruction == II_SUB) exp1.instruction = II_SUB_REV;
1634
    else if (exp1.instruction == II_SUB_REV) exp1.instruction = II_SUB;
1635
    else if (exp1.instruction == II_ADD_ADD) exp1.optionbits ^= 3;
1636
    else if (exp1.instruction == II_MUL_ADD || exp1.instruction == II_MUL_ADD2) exp1.optionbits ^= 0xF;
1637
    else if (exp1.instruction == II_ADD && !(exp1.etype & (XPR_IMMEDIATE | XPR_MEM | XPR_SYM1))) {
1638
        // -(R1+R2) = -R1 -R2 + 0
1639
        exp1.instruction = II_ADD_ADD;
1640
        exp1.value.i = 0;
1641
        exp1.optionbits = 3;
1642
        exp1.etype |= XPR_INT;
1643
    }
1644
    else if (exp1.instruction == II_ADD && (exp1.etype & XPR_IMMEDIATE)) {
1645
        // -(R1+I) = -R1 + (-I)
1646
        exp1.instruction = II_SUB_REV;
1647
        if ((exp1.etype & XPR_IMMEDIATE) == XPR_FLT) exp1.value.d = -exp1.value.d;
1648
        else exp1.value.i = -exp1.value.i;
1649
    }
1650
    else if ((exp1.instruction == 0 || exp1.instruction == II_MUL || exp1.instruction == II_DIV || exp1.instruction == II_DIV_REV)
1651
        && (exp1.etype & XPR_IMMEDIATE)) {
1652
        // -I or -(A*I)
1653
        if (exp1.etype & XPR_FLT) exp1.value.d = -exp1.value.d;
1654
        else exp1.value.i = -exp1.value.i;
1655
    }
1656
    else if (exp1.instruction == II_MUL && !(exp1.etype & XPR_IMMEDIATE)) {
1657
        exp1.instruction = II_MUL_ADD;
1658
        exp1.optionbits ^= 3;
1659
        exp1.etype |= XPR_INT;
1660
    }
1661
    else {
1662
        exp1.etype = XPR_ERROR;
1663
        exp1.value.u = ERR_TOO_COMPLEX; // cannot apply '-' to other expressions
1664
    }
1665
    return exp1;
1666
}
1667
 
1668
// Interpret dyadic expression with string operands
1669
SExpression CAssembler::op2String(uint32_t op, SExpression const & exp1, SExpression const & exp2) {
1670
    if (op != '+') {
1671
        SExpression exp3;
1672
        exp3.etype = XPR_ERROR;
1673
        exp3.value.u = ERR_WRONG_TYPE;
1674
        return exp3;
1675
    }
1676
    // operation is +. concatenate strings, convert numeric to string
1677
 
1678
    uint32_t stringpos1 = stringBuffer.dataSize();  // current position in string buffer
1679
    uint32_t stringpos2;                            // position of second part of concatenated string
1680
    const int maxIntLength = 32;                    // maximum length of integer as string
1681
    const int maxFloatLength = 48;
1682
    const char * wrongType = "-wrong type!-";
1683
    uint32_t len = 0;                               // length of string
1684
 
1685
    // first operand
1686
    if (exp1.etype == XPR_STRING) {
1687
        stringBuffer.push(stringBuffer.buf() + exp1.value.u, exp1.sym2); // copy to string buffer without terminating zero
1688
        stringBuffer.put((char)0);
1689
        //stringpos2 = stringBuffer.dataSize();
1690
    }
1691
    else if (exp1.etype == XPR_INT) {  // convert integer to string
1692
        stringBuffer.push(&exp1, maxIntLength);  // put in anyting here to make space for writing string
1693
        if (sizeof(long int) >= 8) {
1694
#ifndef _WIN32  // suppress warning
1695
            sprintf((char*)stringBuffer.buf()+stringpos1, "%li", exp1.value.i);
1696
#endif
1697
        }
1698
        else {
1699
            sprintf((char*)stringBuffer.buf()+stringpos1, "%lli", (long long)exp1.value.i);
1700
        }
1701
    }
1702
    else if (exp1.etype == XPR_FLT) {  // convert float to string
1703
        stringBuffer.push(&exp1, maxFloatLength);  // put in anyting here to make space for writing string
1704
        sprintf((char*)stringBuffer.buf()+stringpos1, "%g", exp1.value.d);
1705
    }
1706
    else {
1707
        stringBuffer.put(wrongType);
1708
    }
1709
    len = (uint32_t)strlen((char*)stringBuffer.buf()+stringpos1);
1710
    stringpos2 = stringpos1 + len;
1711
    stringBuffer.setSize(stringpos2);  // remove extra space
1712
 
1713
    // second operand
1714
    if (exp2.etype == XPR_STRING) {
1715
        stringBuffer.push(stringBuffer.buf() + exp2.value.u, exp2.sym2); // copy to string buffer without terminating zero
1716
        stringBuffer.put((char)0);
1717
    }
1718
    else if (exp2.etype == XPR_INT) {  // convert integer to string
1719
        stringBuffer.push(&exp2, maxIntLength);  // put in anyting here to make space for writing string
1720
        if (sizeof(long int) >= 8) {
1721
#ifndef _WIN32  // suppress warning
1722
            sprintf((char*)stringBuffer.buf()+stringpos2, "%li", exp2.value.i);
1723
#endif
1724
        }
1725
        else {
1726
            sprintf((char*)stringBuffer.buf()+stringpos2, "%lli", (long long)exp2.value.i);
1727
        }
1728
        len = (uint32_t)strlen((char*)stringBuffer.buf()+stringpos2);
1729
        stringBuffer.setSize(stringpos2 + len + 1);
1730
    }
1731
    else if (exp2.etype == XPR_FLT) {  // convert float to string
1732
        stringBuffer.push(&exp2, maxFloatLength);  // put in anyting here to make space for writing string
1733
        sprintf((char*)stringBuffer.buf()+stringpos2, "%g", exp2.value.d);
1734
        len = (uint32_t)strlen((char*)stringBuffer.buf()+stringpos2);
1735
        stringBuffer.setSize(stringpos2 + len + 1);
1736
    }
1737
    else {
1738
        stringBuffer.put(wrongType);
1739
    }
1740
    SExpression exp3;
1741
    exp3.etype = XPR_STRING;
1742
    exp3.value.u = stringpos1;
1743
    exp3.sym2 = (uint32_t)strlen((char*)stringBuffer.buf() + stringpos1);
1744
    exp3.tokens = exp1.tokens + exp2.tokens + 1;
1745
    return exp3;
1746
}
1747
 
1748
 
1749
double interpretFloat(const char * s, uint32_t length) {
1750
    // interpret floating point number from string with indicated length
1751
    char buffer[64];
1752
    if (length >= sizeof(buffer)) {
1753
        union {
1754
            uint64_t i;
1755
            double d;
1756
        } nan = {0xFFFFC00000000000};
1757
        return nan.d; // return NAN
1758
    }
1759
    memcpy(buffer, s, length);
1760
    buffer[length] = 0;          // terminate string
1761
    double r;
1762
    sscanf(buffer, "%lf", &r);   // convert string to double
1763
    return r;
1764
}
1765
 
1766
// make expression out of symbol
1767
SExpression CAssembler::symbol2expression(uint32_t symi) {
1768
    SExpression expr;
1769
    zeroAllMembers(expr);
1770
 
1771
    switch (symbols[symi].st_type) {
1772
    case STT_CONSTANT:  case STT_VARIABLE:
1773
        expr.etype = XPR_INT;   // default type
1774
        expr.sym1 = symi;
1775
        if (symbols[symi].st_other & STV_FLOAT) expr.etype = XPR_FLT;
1776
        if (symbols[symi].st_other & STV_STRING) {
1777
            expr.etype = XPR_STRING;
1778
            expr.sym2 = (uint32_t)symbols[symi].st_unitnum;
1779
        }
1780
        expr.value.u = symbols[symi].st_value;
1781
        break;
1782
    case STT_EXPRESSION:
1783
        if (symbols[symi].st_value < expressions.numEntries()) {
1784
            expr = expressions[uint32_t(symbols[symi].st_value)];
1785
        }
1786
        else {
1787
            expr.etype = XPR_ERROR;
1788
            expr.value.u = TOK_XPR;
1789
        }
1790
        break;
1791
    default:
1792
        expr.etype = XPR_ERROR;
1793
        expr.value.u = ERR_CONFLICT_TYPE;
1794
    }
1795
    expr.tokens = 0;
1796
    return expr;
1797
}

powered by: WebSVN 2.1.0

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