int main(int argc, char* argv[]) { printf("%d\n", IntLt(1, 2)); printf("%d\n", IntGt(2, 1)); printf("%d\n", IntEq(2, 2)); int n = -1; printf("%d\n", IntLt(n, (unsigned int)1)); printf("%d\n", IntLt(n, (int)1)); uint64_t i64 = 1; int32_t i32 = -2; int16_t i16 = -9; printf("%d\n", IntGt(i64, i32)); printf("%d\n", IntLt(i16, i32)); size_t a = 100; signed long b = -9; int c = 17; printf("%d\n", IntGt(a, b)); printf("%d\n", IntLt(b, a)); printf("%d\n", IntGe(b, i16)); printf("%d\n", IntLe(b, i16)); printf("%d\n", IntLe(b, 'a')); printf("%d\n", IntGt(c, i64)); printf("%d\n", IntGt(uint32_t(18), c)); printf("%u\n", sizeof(long long)); RunTest(); return 0; }
Int16 VarTestReplace(Var ** p_var, Var * from, Var * to) /* Purpose: Create variable where 'from' variable is replaced by 'to' variable. Return number of replacements made (0 if none). */ { Var * var, * var2; Int16 n = 0; Int16 n2, n3; Var * v2, * v3; var = *p_var; if (var != NULL) { // TODO: We basically garantee that the int valueas are the same variable if (var == from || (var->mode == INSTR_INT && from->mode == INSTR_INT && IntEq(&var->n, &from->n))) { *p_var = to; n++; } else { if (var->mode == INSTR_INT) { // const does not get replaced } else if (var->mode == INSTR_TEXT) { } else if (var->mode == INSTR_VAR) { if (var->adr != NULL) { *p_var = var->adr; n = VarTestReplace(p_var, from, to); } } else if (var->mode == INSTR_CONST) { } else /*if (var->mode == INSTR_ELEMENT || var->mode == INSTR_BYTE || var->mode == INSTR_TUPLE)*/ { v2 = var->adr; v3 = var->var; n2 = VarTestReplace(&v2, from, to); n3 = VarTestReplace(&v3, from, to); // In case something was replaced, we must allocate new element, as we must not modify original variable // TODO: Use VarNewElement. if (n2 > 0 || n3 > 0) { var2 = VarAllocUnused(); memcpy(var2, var, sizeof(Var)); var2->adr = v2; var2->var = v3; var2->next = NULL; n += n2 + n3; *p_var = var2; } } /*if (var->mode == INSTR_VAR && var->adr != NULL) { *p_var = var->adr; n = VarTestReplace(p_var, from, to); }*/ } } return n; }
static Bool ArgMatch(RuleArg * pattern, Var * arg, RuleArgVariant parent_variant) { Type * atype; Var * pvar, * left, * right; UInt8 j; RuleArgVariant v = pattern->variant; if (arg == NULL) return v == RULE_ANY; atype = arg->type; switch(v) { case RULE_ADD: case RULE_SUB: right = arg->var; // If we have variable and not arithmetic operation, try to match using substraction or addition with 0 // %A => %A-0 or %A+0 if (arg->mode == INSTR_VAR || arg->mode == INSTR_INT) { left = arg; right = ZERO; } else { if (v == RULE_ADD && arg->mode != INSTR_ADD) return false; if (v == RULE_SUB && arg->mode != INSTR_SUB) return false; left = arg->adr; } if (!ArgMatch(pattern->index, right, v)) return false; return ArgMatch(pattern->arr, left, v); break; // <X>..<Y> case RULE_RANGE: if (arg->mode != INSTR_RANGE) return false; // pattern expects element, and variable is not an element if (!ArgMatch(pattern->index, arg->var, v)) return false; return ArgMatch(pattern->arr, arg->adr, v); break; // In case of destination register, we ignore all flag registers, that are specified in pattern and not specified in argument. // I.e. instruction may affect more flags, than the source instruction requires. // All flags defined by source instruction (argument) must be part of pattern though. // <X>,<Y> case RULE_TUPLE: if (arg->mode != INSTR_TUPLE) return false; if (!ArgMatch(pattern->index, arg->var, v)) return false; return ArgMatch(pattern->arr, arg->adr, v); break; // <X>$<Y> case RULE_BYTE: if (arg->mode != INSTR_BYTE) return false; // pattern expects byte, and variable is not an byte if (!ArgMatch(pattern->index, arg->var, v)) return false; return ArgMatch(pattern->arr, arg->adr, v); break; // <X>(<Y>) case RULE_ELEMENT: if (arg->mode != INSTR_ELEMENT) return false; // pattern expects element, and variable is not an element if (!ArgMatch(pattern->index, arg->var, v)) return false; return ArgMatch(pattern->arr, arg->adr, v); break; // const %A:type case RULE_CONST: if (!VarIsConst(arg)) return false; if (!VarMatchesPattern(arg, pattern)) return false; break; // Exact variable. case RULE_REGISTER: pvar = pattern->var; if (VarIsConst(pvar)) { if (!VarIsConst(arg)) return false; if (pvar->mode == INSTR_TEXT) { if (!StrEqual(pvar->str, arg->str)) return false; } else if (pvar->mode == INSTR_INT) { // if (pvar->value_nonempty) { if (arg->mode != INSTR_INT || !IntEq(&pvar->n, &arg->n)) return false; // } } } else { if (pattern->var != NULL && !VarIsEqual(arg, pattern->var)) return false; } break; case RULE_VARIANT: if (!VarIsOneOf(arg, pattern->var)) return false; break; case RULE_VARIABLE: if (arg->mode != INSTR_VAR) return false; if (FlagOn(arg->submode, SUBMODE_REG)) return false; if (parent_variant != RULE_BYTE && !VarMatchesPattern(arg, pattern)) return false; break; // @%A case RULE_DEREF: if (arg->mode != INSTR_DEREF) return false; arg = arg->var; if (!ArgMatch(pattern->arr, arg, v)) return false; // if (!VarMatchesPattern(arg, pattern)) return false; break; // %A:type case RULE_ARG: // In Emit phase, we need to exactly differentiate between single variable and byte offset. if (arg->mode == INSTR_VAR || VarIsConst(arg) || (arg->mode == INSTR_BYTE && MATCH_MODE != PHASE_EMIT)) { if (parent_variant != RULE_TUPLE && FlagOn(arg->submode, SUBMODE_REG)) return false; if (!VarMatchesPattern(arg, pattern)) return false; } else { return false; } // if (arg->mode == INSTR_DEREF || arg->mode == INSTR_RANGE || (arg->mode == INSTR_BYTE && MATCH_MODE == PHASE_EMIT) || arg->mode == INSTR_ELEMENT) return false; // if (parent_variant != RULE_TUPLE && FlagOn(arg->submode, SUBMODE_REG)) return false; // if (!VarMatchesPattern(arg, pattern)) return false; break; case RULE_ANY: break; default: break; } // If there is macro argument number %A-%Z specified in rule argument, we set or check it here if (pattern->arg_no != 0) { // For array element variable store array into the macro argument pvar = arg; // if (arg->mode == INSTR_ELEMENT && !VarIsStructElement(arg)) { // pvar = arg->adr; // } j = pattern->arg_no-1; if (MACRO_ARG[j] == NULL) { MACRO_ARG[j] = pvar; } else { if (MACRO_ARG[j] != pvar) return false; } // Set the index items // if (pattern->index != NULL) { // if (!ArgMatch(pattern->index, arg->var)) return false; // } } return true; }