value* shader::get_gpr_value(bool src, unsigned reg, unsigned chan, bool rel, unsigned version) { sel_chan id(reg, chan); value *v; gpr_array *a = get_gpr_array(reg, chan); if (rel) { assert(a); v = create_value(VLK_REL_REG, id, 0); v->rel = get_special_value(SV_AR_INDEX); fill_array_values(a, v->muse); if (!src) fill_array_values(a, v->mdef); } else { if (version == 0 && reg < prep_regs_count) return (val_pool[id - 1]); v = get_value(VLK_REG, id, version); } v->array = a; v->pin_gpr = v->select; return v; }
/* Parse and expand text after '$' character. return value has to be g_free()'d if `free_ret' is TRUE. */ char *parse_special(char **cmd, SERVER_REC *server, void *item, char **arglist, int *free_ret, int *arg_used) { static char **nested_orig_cmd = NULL; /* FIXME: KLUDGE! */ char command, *value; char align_pad; int align, align_flags; char *nest_value; int brackets, nest_free; *free_ret = FALSE; command = **cmd; (*cmd)++; switch (command) { case '[': /* alignment */ if (!get_alignment_args(cmd, &align, &align_flags, &align_pad) || **cmd == '\0') { (*cmd)--; return NULL; } break; default: command = 0; (*cmd)--; } nest_free = FALSE; nest_value = NULL; if (**cmd == '(') { /* subvariable */ int toplevel = nested_orig_cmd == NULL; if (toplevel) nested_orig_cmd = cmd; (*cmd)++; if (**cmd != '$') { /* ... */ nest_value = *cmd; } else { (*cmd)++; nest_value = parse_special(cmd, server, item, arglist, &nest_free, arg_used); } while ((*nested_orig_cmd)[1] != '\0') { (*nested_orig_cmd)++; if (**nested_orig_cmd == ')') break; } cmd = &nest_value; if (toplevel) nested_orig_cmd = NULL; } if (**cmd != '{') brackets = FALSE; else { /* special value is inside {...} (foo${test}bar -> fooXXXbar) */ (*cmd)++; brackets = TRUE; } value = get_special_value(cmd, server, item, arglist, free_ret, arg_used); if (**cmd == '\0') g_error("parse_special() : buffer overflow!"); if (brackets) { while (**cmd != '}' && (*cmd)[1] != '\0') (*cmd)++; } if (nest_free) g_free(nest_value); if (command == '[') { /* alignment */ char *p; if (value == NULL) return ""; p = get_alignment(value, align, align_flags, align_pad); if (*free_ret) g_free(value); *free_ret = TRUE; return p; } return value; }