/*1* Copyright (c) 2017 Rob Clark <[email protected]>2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,19* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE20* SOFTWARE.21*/2223#ifndef _ASM_H_24#define _ASM_H_2526#include <stdbool.h>27#include <stdint.h>28#include "afuc.h"2930extern int gpuver;3132/**33* Intermediate representation for an instruction, before final encoding.34* This mostly exists because we need to resolve label offset's in a 2nd35* pass, but also so that parser.y doesn't really need to care so much36* about the different encodings for 2src regs vs 1src+immed, or mnemonics37*/38struct asm_instruction {39int tok;40int dst;41int src1;42int src2;43int immed;44int shift;45int bit;46int xmov;47uint32_t literal;48const char *label;4950bool has_immed : 1;51bool has_shift : 1;52bool has_bit : 1;53bool is_literal : 1;54bool rep : 1;55};5657struct asm_label {58unsigned offset;59const char *label;60};6162struct asm_instruction *next_instr(int tok);63void decl_label(const char *str);6465static inline uint32_t66parse_reg(const char *str)67{68char *retstr;69long int ret;7071if (!strcmp(str, "$rem"))72return REG_REM;73else if (!strcmp(str, "$memdata"))74return REG_MEMDATA;75else if (!strcmp(str, "$addr"))76return REG_ADDR;77else if (!strcmp(str, "$regdata"))78return REG_REGDATA;79else if (!strcmp(str, "$usraddr"))80return REG_USRADDR;81else if (!strcmp(str, "$data"))82return 0x1f;8384ret = strtol(str + 1, &retstr, 16);8586if (*retstr != '\0') {87printf("invalid register: %s\n", str);88exit(2);89}9091return ret;92}9394static inline uint32_t95parse_literal(const char *str)96{97char *retstr;98long int ret;99100ret = strtol(str + 1, &retstr, 16);101102if (*retstr != ']') {103printf("invalid literal: %s\n", str);104exit(2);105}106107return ret;108}109110static inline uint32_t111parse_bit(const char *str)112{113return strtol(str + 1, NULL, 10);114}115116unsigned parse_control_reg(const char *name);117118/* string trailing ':' off label: */119static inline const char *120parse_label_decl(const char *str)121{122char *s = strdup(str);123s[strlen(s) - 1] = '\0';124return s;125}126127void yyset_in(FILE *_in_str);128129#endif /* _ASM_H_ */130131132