1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <errno.h> 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <regex.h> 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdlib.h> 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdio.h> 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <string.h> 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <sys/types.h> 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "../radeon_compiler_util.h" 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "../radeon_opcodes.h" 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "../radeon_program.h" 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "rc_test_helpers.h" 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* This file contains some helper functions for filling out the rc_instruction 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * data structures. These functions take a string as input based on the format 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * output by rc_program_print(). 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define VERBOSE 0 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DBG(...) do { if (VERBOSE) fprintf(stderr, __VA_ARGS__); } while(0) 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define REGEX_ERR_BUF_SIZE 50 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct match_info { 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char * String; 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int Length; 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int match_length(regmatch_t * matches, int index) 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return matches[index].rm_eo - matches[index].rm_so; 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int regex_helper( 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char * regex_str, 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char * search_str, 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org regmatch_t * matches, 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int num_matches) 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org char err_buf[REGEX_ERR_BUF_SIZE]; 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org regex_t regex; 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int err_code; 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int i; 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org err_code = regcomp(®ex, regex_str, REG_EXTENDED); 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (err_code) { 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org regerror(err_code, ®ex, err_buf, REGEX_ERR_BUF_SIZE); 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fprintf(stderr, "Failed to compile regex: %s\n", err_buf); 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org err_code = regexec(®ex, search_str, num_matches, matches, 0); 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DBG("Search string: '%s'\n", search_str); 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < num_matches; i++) { 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DBG("Match %u start = %d end = %d\n", i, 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org matches[i].rm_so, matches[i].rm_eo); 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (err_code) { 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org regerror(err_code, ®ex, err_buf, REGEX_ERR_BUF_SIZE); 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fprintf(stderr, "Failed to match regex: %s\n", err_buf); 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 1; 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define REGEX_SRC_MATCHES 6 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct src_tokens { 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct match_info Negate; 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct match_info Abs; 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct match_info File; 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct match_info Index; 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct match_info Swizzle; 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Initialize the source register at index src_index for the instruction based 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * on src_str. 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * NOTE: Warning in init_rc_normal_instruction() applies to this function as 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * well. 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param src_str A string that represents the source register. The format for 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * this string is the same that is output by rc_program_print. 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @return 1 On success, 0 on failure 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint init_rc_normal_src( 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst, 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int src_index, 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char * src_str) 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char * regex_str = "(-*)(\\|*)([[:lower:]]*)\\[([[:digit:]])\\](\\.*[[:lower:]-]*)"; 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org regmatch_t matches[REGEX_SRC_MATCHES]; 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct src_tokens tokens; 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_src_register * src_reg = &inst->U.I.SrcReg[src_index]; 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int i; 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Execute the regex */ 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!regex_helper(regex_str, src_str, matches, REGEX_SRC_MATCHES)) { 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fprintf(stderr, "Failed to execute regex for src register.\n"); 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Create Tokens */ 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.Negate.String = src_str + matches[1].rm_so; 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.Negate.Length = match_length(matches, 1); 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.Abs.String = src_str + matches[2].rm_so; 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.Abs.Length = match_length(matches, 2); 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.File.String = src_str + matches[3].rm_so; 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.File.Length = match_length(matches, 3); 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.Index.String = src_str + matches[4].rm_so; 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.Index.Length = match_length(matches, 4); 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.Swizzle.String = src_str + matches[5].rm_so; 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.Swizzle.Length = match_length(matches, 5); 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Negate */ 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tokens.Negate.Length > 0) { 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_reg->Negate = RC_MASK_XYZW; 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Abs */ 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tokens.Abs.Length > 0) { 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_reg->Abs = 1; 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* File */ 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!strncmp(tokens.File.String, "temp", tokens.File.Length)) { 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_reg->File = RC_FILE_TEMPORARY; 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (!strncmp(tokens.File.String, "input", tokens.File.Length)) { 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_reg->File = RC_FILE_INPUT; 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (!strncmp(tokens.File.String, "const", tokens.File.Length)) { 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_reg->File = RC_FILE_CONSTANT; 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (!strncmp(tokens.File.String, "none", tokens.File.Length)) { 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_reg->File = RC_FILE_NONE; 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Index */ 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errno = 0; 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_reg->Index = strtol(tokens.Index.String, NULL, 10); 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (errno > 0) { 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fprintf(stderr, "Could not convert src register index.\n"); 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Swizzle */ 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tokens.Swizzle.Length == 0) { 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_reg->Swizzle = RC_SWIZZLE_XYZW; 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int str_index = 1; 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_reg->Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_UNUSED); 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tokens.Swizzle.String[0] != '.') { 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fprintf(stderr, "First char of swizzle is not valid.\n"); 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < 4; i++, str_index++) { 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tokens.Swizzle.String[str_index] == '-') { 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_reg->Negate |= (1 << i); 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org str_index++; 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(tokens.Swizzle.String[str_index]) { 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 'x': 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SET_SWZ(src_reg->Swizzle, i, RC_SWIZZLE_X); 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 'y': 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SET_SWZ(src_reg->Swizzle, i, RC_SWIZZLE_Y); 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 'z': 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SET_SWZ(src_reg->Swizzle, i, RC_SWIZZLE_Z); 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 'w': 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SET_SWZ(src_reg->Swizzle, i, RC_SWIZZLE_W); 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case '1': 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SET_SWZ(src_reg->Swizzle, i, RC_SWIZZLE_ONE); 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case '0': 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SET_SWZ(src_reg->Swizzle, i, RC_SWIZZLE_ZERO); 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 'H': 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SET_SWZ(src_reg->Swizzle, i, RC_SWIZZLE_HALF); 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case '_': 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SET_SWZ(src_reg->Swizzle, i, RC_SWIZZLE_UNUSED); 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fprintf(stderr, "Unknown src register swizzle.\n"); 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DBG("File=%u index=%u swizzle=%x negate=%u abs=%u\n", 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_reg->File, src_reg->Index, src_reg->Swizzle, 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_reg->Negate, src_reg->Abs); 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 1; 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define REGEX_DST_MATCHES 4 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct dst_tokens { 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct match_info File; 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct match_info Index; 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct match_info WriteMask; 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Initialize the destination for the instruction based on dst_str. 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * NOTE: Warning in init_rc_normal_instruction() applies to this function as 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * well. 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param dst_str A string that represents the destination register. The format 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * for this string is the same that is output by rc_program_print. 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @return 1 On success, 0 on failure 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint init_rc_normal_dst( 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst, 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char * dst_str) 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char * regex_str = "([[:lower:]]*)\\[([[:digit:]]*)\\](\\.*[[:lower:]]*)"; 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org regmatch_t matches[REGEX_DST_MATCHES]; 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct dst_tokens tokens; 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int i; 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Execute the regex */ 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!regex_helper(regex_str, dst_str, matches, REGEX_DST_MATCHES)) { 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fprintf(stderr, "Failed to execute regex for dst register.\n"); 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Create Tokens */ 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.File.String = dst_str + matches[1].rm_so; 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.File.Length = match_length(matches, 1); 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.Index.String = dst_str + matches[2].rm_so; 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.Index.Length = match_length(matches, 2); 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.WriteMask.String = dst_str + matches[3].rm_so; 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.WriteMask.Length = match_length(matches, 3); 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* File Type */ 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!strncmp(tokens.File.String, "temp", tokens.File.Length)) { 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.File = RC_FILE_TEMPORARY; 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (!strncmp(tokens.File.String, "output", tokens.File.Length)) { 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.File = RC_FILE_OUTPUT; 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fprintf(stderr, "Unknown dst register file type.\n"); 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* File Index */ 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errno = 0; 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.Index = strtol(tokens.Index.String, NULL, 10); 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (errno > 0) { 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fprintf(stderr, "Could not convert dst register index\n"); 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* WriteMask */ 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tokens.WriteMask.Length == 0) { 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.WriteMask = RC_MASK_XYZW; 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The first character should be '.' */ 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tokens.WriteMask.String[0] != '.') { 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fprintf(stderr, "1st char of writemask is not valid.\n"); 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 1; i < tokens.WriteMask.Length; i++) { 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(tokens.WriteMask.String[i]) { 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 'x': 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.WriteMask |= RC_MASK_X; 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 'y': 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.WriteMask |= RC_MASK_Y; 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 'z': 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.WriteMask |= RC_MASK_Z; 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 'w': 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.WriteMask |= RC_MASK_W; 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fprintf(stderr, "Unknown swizzle in writemask.\n"); 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DBG("Dst Reg File=%u Index=%d Writemask=%d\n", 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.File, 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.Index, 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.WriteMask); 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 1; 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define REGEX_INST_MATCHES 7 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct inst_tokens { 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct match_info Opcode; 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct match_info Sat; 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct match_info Dst; 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct match_info Srcs[3]; 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Initialize a normal instruction based on inst_str. 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * WARNING: This function might not be able to handle every kind of format that 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * rc_program_print() can output. If you are having problems with a 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * particular string, you may need to add support for it to this functions. 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param inst_str A string that represents the source register. The format for 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * this string is the same that is output by rc_program_print. 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @return 1 On success, 0 on failure 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint init_rc_normal_instruction( 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst, 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char * inst_str) 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char * regex_str = "([[:upper:]]+)(_SAT)* ([^,]*)[, ]*([^,]*)[, ]*([^,]*)[, ]*([^;]*)"; 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int i; 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org regmatch_t matches[REGEX_INST_MATCHES]; 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct inst_tokens tokens; 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Initialize inst */ 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(inst, 0, sizeof(struct rc_instruction)); 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->Type = RC_INSTRUCTION_NORMAL; 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Execute the regex */ 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!regex_helper(regex_str, inst_str, matches, REGEX_INST_MATCHES)) { 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&tokens, 0, sizeof(tokens)); 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Create Tokens */ 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.Opcode.String = inst_str + matches[1].rm_so; 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.Opcode.Length = match_length(matches, 1); 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (matches[2].rm_so > -1) { 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.Sat.String = inst_str + matches[2].rm_so; 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.Sat.Length = match_length(matches, 2); 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Fill out the rest of the instruction. */ 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < MAX_RC_OPCODE; i++) { 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct rc_opcode_info * info = rc_get_opcode_info(i); 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int first_src = 3; 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int j; 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (strncmp(tokens.Opcode.String, info->Name, tokens.Opcode.Length)) { 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.Opcode = info->Opcode; 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (info->HasDstReg) { 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org char * dst_str; 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.Dst.String = inst_str + matches[3].rm_so; 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.Dst.Length = match_length(matches, 3); 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org first_src++; 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst_str = malloc(sizeof(char) * (tokens.Dst.Length + 1)); 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org strncpy(dst_str, tokens.Dst.String, tokens.Dst.Length); 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst_str[tokens.Dst.Length] = '\0'; 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org init_rc_normal_dst(inst, dst_str); 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(dst_str); 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (j = 0; j < info->NumSrcRegs; j++) { 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org char * src_str; 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.Srcs[j].String = 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_str + matches[first_src + j].rm_so; 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.Srcs[j].Length = 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org match_length(matches, first_src + j); 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_str = malloc(sizeof(char) * 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (tokens.Srcs[j].Length + 1)); 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org strncpy(src_str, tokens.Srcs[j].String, 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tokens.Srcs[j].Length); 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_str[tokens.Srcs[j].Length] = '\0'; 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org init_rc_normal_src(inst, j, src_str); 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 1; 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 381