1/*
2 * Copyright (c) 2017 Rob Clark <robdclark@gmail.com>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24#ifndef _ASM_H_
25#define _ASM_H_
26
27#include <stdbool.h>
28#include <stdint.h>
29#include "afuc.h"
30
31extern int gpuver;
32
33/**
34 * Intermediate representation for an instruction, before final encoding.
35 * This mostly exists because we need to resolve label offset's in a 2nd
36 * pass, but also so that parser.y doesn't really need to care so much
37 * about the different encodings for 2src regs vs 1src+immed, or mnemonics
38 */
39struct asm_instruction {
40   int tok;
41   int dst;
42   int src1;
43   int src2;
44   int immed;
45   int shift;
46   int bit;
47   int xmov;
48   uint32_t literal;
49   const char *label;
50
51   bool has_immed : 1;
52   bool has_shift : 1;
53   bool has_bit : 1;
54   bool is_literal : 1;
55   bool rep : 1;
56};
57
58struct asm_label {
59   unsigned offset;
60   const char *label;
61};
62
63struct asm_instruction *next_instr(int tok);
64void decl_label(const char *str);
65
66static inline uint32_t
67parse_reg(const char *str)
68{
69   char *retstr;
70   long int ret;
71
72   if (!strcmp(str, "$rem"))
73      return REG_REM;
74   else if (!strcmp(str, "$memdata"))
75      return REG_MEMDATA;
76   else if (!strcmp(str, "$addr"))
77      return REG_ADDR;
78   else if (!strcmp(str, "$regdata"))
79      return REG_REGDATA;
80   else if (!strcmp(str, "$usraddr"))
81      return REG_USRADDR;
82   else if (!strcmp(str, "$data"))
83      return 0x1f;
84
85   ret = strtol(str + 1, &retstr, 16);
86
87   if (*retstr != '\0') {
88      printf("invalid register: %s\n", str);
89      exit(2);
90   }
91
92   return ret;
93}
94
95static inline uint32_t
96parse_literal(const char *str)
97{
98   char *retstr;
99   long int ret;
100
101   ret = strtol(str + 1, &retstr, 16);
102
103   if (*retstr != ']') {
104      printf("invalid literal: %s\n", str);
105      exit(2);
106   }
107
108   return ret;
109}
110
111static inline uint32_t
112parse_bit(const char *str)
113{
114   return strtol(str + 1, NULL, 10);
115}
116
117unsigned parse_control_reg(const char *name);
118
119/* string trailing ':' off label: */
120static inline const char *
121parse_label_decl(const char *str)
122{
123   char *s = strdup(str);
124   s[strlen(s) - 1] = '\0';
125   return s;
126}
127
128void yyset_in(FILE *_in_str);
129
130#endif /* _ASM_H_ */
131