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