static int postfix_member_offset = 0;
static int postfix_member_size = 0;
+static int postfix_value_is_array = 0;
static int postfix_member_is_floating = 0;
static int postfix_member_is_unsigned = 0;
if (find_global_symbol (name) >= 0) {
+ postfix_value_is_array = get_global_symbol_array (name);
+
if (get_global_symbol_kind (name) == GLOBAL_SYMBOL_FUNCTION ||
get_global_symbol_array (name) ||
(!get_global_symbol_pointer_depth (name) &&
postfix_member_pointed_size = elem_size;
postfix_member_offset = offset;
postfix_member_size = size;
+ postfix_value_is_array = is_array;
postfix_member_is_floating = is_floating;
postfix_member_is_unsigned = is_unsigned;
postfix_member_calling_convention = last_found_member_calling_convention;
enum token_kind assign_op;
int subscript_elem_size;
+ postfix_value_is_array = 0;
+
if (!is_array && pointer_depth > 0) {
emit_load_member_from_addr_reg_now (reg, reg, offset, DATA_PTR & 0x1f);
} else if (state->ofp && offset != 0) {
}
+static int source_starts_lparen_subscript_call_at (const char *p) {
+
+ int bracket_depth;
+
+ if (!p || *p != '(') {
+ return 0;
+ }
+
+ p++;
+
+ while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
+ p++;
+ }
+
+ if (!((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || *p == '_')) {
+ return 0;
+ }
+
+ p++;
+
+ while ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || (*p >= '0' && *p <= '9') || *p == '_') {
+ p++;
+ }
+
+ while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
+ p++;
+ }
+
+ if (*p != '[') {
+ return 0;
+ }
+
+ bracket_depth = 1;
+ p++;
+
+ while (*p && bracket_depth > 0) {
+
+ if (*p == '[') {
+ bracket_depth++;
+ } else if (*p == ']') {
+ bracket_depth--;
+ }
+
+ p++;
+
+ }
+
+ if (bracket_depth != 0) {
+ return 0;
+ }
+
+ while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
+ p++;
+ }
+
+ if (*p != ')') {
+ return 0;
+ }
+
+ p++;
+
+ while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
+ p++;
+ }
+
+ return *p == '(';
+
+}
+
+static int source_starts_lparen_deref_subscript_call_at (const char *p) {
+
+ int bracket_depth;
+
+ if (!p) {
+ return 0;
+ }
+
+ if (*p == '(') {
+ p++;
+ }
+
+ while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
+ p++;
+ }
+
+ if (*p != '*') {
+ return 0;
+ }
+
+ p++;
+
+ while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
+ p++;
+ }
+
+ if (!((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || *p == '_')) {
+ return 0;
+ }
+
+ p++;
+
+ while ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || (*p >= '0' && *p <= '9') || *p == '_') {
+ p++;
+ }
+
+ while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
+ p++;
+ }
+
+ if (*p != '[') {
+ return 0;
+ }
+
+ bracket_depth = 1;
+ p++;
+
+ while (*p && bracket_depth > 0) {
+
+ if (*p == '[') {
+ bracket_depth++;
+ } else if (*p == ']') {
+ bracket_depth--;
+ }
+
+ p++;
+
+ }
+
+ if (bracket_depth != 0) {
+ return 0;
+ }
+
+ while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
+ p++;
+ }
+
+ if (*p != ')') {
+ return 0;
+ }
+
+ p++;
+
+ while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
+ p++;
+ }
+
+ return *p == '(';
+
+}
+
static int source_starts_lparen_deref_postfix_incdec_at (const char *p) {
if (!p) {
if (src->is_array) {
+ postfix_value_is_array = 1;
+
if (src->is_static && src->static_label) {
emit_load_address_to_reg_now (reg, src->static_label);
} else {
if (find_global_symbol (name) >= 0) {
+ postfix_value_is_array = get_global_symbol_array (name);
+
if (get_global_symbol_kind (name) == GLOBAL_SYMBOL_FUNCTION ||
get_global_symbol_array (name) ||
(!get_global_symbol_pointer_depth (name) &&
static void emit_load_assignment_rhs_expression_to_reg (const char *reg);
+static int local_symbol_is_array_now (const struct local_symbol *sym) {
+
+ if (!sym) {
+ return 0;
+ }
+
+ return sym->is_array || sym->array_dimensions > 0 || sym->array_element_size > 0;
+
+}
+
static int current_argument_is_bare_identifier_now (void) {
const char *p;
int offset;
int chunk;
- if (!name || get_global_symbol_kind (name) != GLOBAL_SYMBOL_OBJECT ||
- get_global_symbol_array (name) || get_global_symbol_pointer_depth (name) > 0 ||
- get_global_symbol_floating (name)) {
+ const char *tag_name;
+
+ if (!name) {
return 0;
}
- size = get_global_symbol_size (name);
+ if (get_global_symbol_kind (name) != GLOBAL_SYMBOL_OBJECT) {
+ return 0;
+ }
+
+ if (get_global_symbol_array (name)) {
+ return 0;
+ }
+ if (get_global_symbol_pointer_depth (name) > 0) {
+ return 0;
+ }
+
+ if (get_global_symbol_floating (name)) {
+ return 0;
+ }
+
+ size = get_global_symbol_size (name);
+ tag_name = get_global_symbol_tag_name (name);
+
+ /*
+ * Only tagged aggregate objects are passed by value here. Untagged
+ * objects include scalar values and arrays whose decay metadata was not
+ * visible during the self-hosting pass; those must use normal expression
+ * loading so arrays decay to one address instead of multiple stack words.
+ */
+ if (!tag_name || !tag_name[0]) {
+ return 0;
+ }
+
if (size <= (DATA_PTR & 0x1f)) {
return 0;
}
}
+ postfix_value_is_array = 0;
postfix_member_seen = 0;
postfix_member_size = 0;
postfix_member_pointer_depth = 0;
postfix_member_pointed_size = 0;
- if (tok.kind == TOK_IDENT && tok.ident && current_argument_is_bare_identifier_now () && find_local_symbol (tok.ident) && find_local_symbol (tok.ident)->is_array) {
+ if (tok.kind == TOK_IDENT && tok.ident && current_argument_is_bare_identifier_now () && find_local_symbol (tok.ident) && local_symbol_is_array_now (find_local_symbol (tok.ident))) {
struct local_symbol *arg_sym = find_local_symbol (tok.ident);
if (state->ofp) {
- if (!arg_is_floating && postfix_member_seen && postfix_member_pointer_depth == 0 && postfix_member_size > (DATA_PTR & 0x1f)) {
+ if (!arg_is_floating && postfix_member_seen && postfix_member_pointer_depth == 0 && !postfix_value_is_array && postfix_member_size > (DATA_PTR & 0x1f)) {
arg_bytes = postfix_member_size;
emit_push_aggregate_from_addr_reg_now ("rax", arg_bytes);
- } else if (!arg_is_floating && postfix_member_size > (DATA_PTR & 0x1f)) {
+ } else if (!arg_is_floating && !postfix_value_is_array && postfix_member_size > (DATA_PTR & 0x1f)) {
arg_bytes = postfix_member_size;
emit_push_aggregate_from_addr_reg_now ("rax", arg_bytes);
}
+ postfix_value_is_array = 0;
postfix_member_seen = 0;
postfix_member_size = 0;
postfix_member_pointer_depth = 0;
postfix_member_pointed_size = 0;
- if (tok.kind == TOK_IDENT && tok.ident && current_argument_is_bare_identifier_now () && find_local_symbol (tok.ident) && find_local_symbol (tok.ident)->is_array) {
+ if (tok.kind == TOK_IDENT && tok.ident && current_argument_is_bare_identifier_now () && find_local_symbol (tok.ident) && local_symbol_is_array_now (find_local_symbol (tok.ident))) {
struct local_symbol *arg_sym = find_local_symbol (tok.ident);
* slot according to the AMD64 calling convention.
*/
- } else if (!use_inline && !arg_is_floating && postfix_member_seen && postfix_member_pointer_depth == 0 && postfix_member_size > (DATA_PTR & 0x1f)) {
+ } else if (!use_inline && !arg_is_floating && postfix_member_seen && postfix_member_pointer_depth == 0 && !postfix_value_is_array && postfix_member_size > (DATA_PTR & 0x1f)) {
arg_bytes = postfix_member_size;
emit_push_aggregate_from_addr_reg_now ("rax", arg_bytes);
- } else if (!use_inline && !arg_is_floating && postfix_member_size > (DATA_PTR & 0x1f)) {
+ } else if (!use_inline && !arg_is_floating && !postfix_value_is_array && postfix_member_size > (DATA_PTR & 0x1f)) {
arg_bytes = postfix_member_size;
emit_push_aggregate_from_addr_reg_now ("rax", arg_bytes);
}
+ if (tok.kind == TOK_LPAREN) {
+
+ get_token ();
+
+ expect (TOK_RPAREN, ")");
+ emit_call_pointer_in_reg_now ("rax", "rax");
+
+ }
+
emit_load_deref_reg_now ("rax", DATA_PTR & 0x1f);
emit_handle_subscript_after_loaded_pointer_to_reg_now ("rax", pointer_depth - 1, pointed_size, src ? src->pointed_is_unsigned : get_global_symbol_pointed_is_unsigned (name));
emit_parse_postfix_subscript_scaled_address_to_reg_now ("rdx", elem_size);
}
+ if (tok.kind == TOK_LPAREN) {
+
+ if (state->ofp) {
+ emit_load_deref_reg_now ("rdx", DATA_PTR & 0x1f);
+ }
+
+ emit_call_pointer_in_reg_now ("rdx", "rax");
+ expect_semi_or_recover ();
+
+ free (name);
+ return 1;
+
+ }
+
if (tok.kind == TOK_INCR || tok.kind == TOK_DECR) {
op = tok.kind;
const char *base_tag_name = 0;
- if (tok.kind != TOK_LPAREN || !source_starts_with_parenthesized_indirect_call_now ()) {
+ if (tok.kind != TOK_LPAREN || (!source_starts_with_parenthesized_indirect_call_now () && !source_starts_lparen_deref_subscript_call_at (tok.start) && !source_starts_lparen_deref_subscript_call_at (tok.caret) && !source_starts_lparen_subscript_call_at (tok.start) && !source_starts_lparen_subscript_call_at (tok.caret))) {
return 0;
}
get_token ();
- if (tok.kind != TOK_STAR) {
- return 0;
+ if (tok.kind == TOK_STAR) {
+ get_token ();
}
- get_token ();
-
if (tok.kind == TOK_LPAREN) {
wrapped_member_expr = 1;
}
+ if (parse_parenthesized_member_function_pointer_call_statement ()) {
+ return;
+ }
+
if (parse_parenthesized_deref_subscript_statement ()) {
expect_semi_or_recover ();
}
- if (parse_parenthesized_member_function_pointer_call_statement ()) {
- return;
- }
-
if (tok.kind == TOK_LPAREN) {
int parenthesized_assignment_is_unsigned;
}
-static int int64_is_zero_value (int64_s value) {
- return value.low == 0 && value.high == 0;
+static int int64_is_zero_value (const int64_s *value) {
+ return value->low == 0 && value->high == 0;
}
static char masm_pending_data_label[512];
int i;
if (symbols) {
+
for (i = 0; i < value_count; i++) {
+
if (symbols[i]) {
return 0;
}
+
}
+
}
if (!values || value_count <= 0) {
}
for (i = 0; i < value_count; i++) {
- if (!int64_is_zero_value (values[i])) {
+
+ if (!int64_is_zero_value (&values[i])) {
return 0;
}
+
}
return 1;
static int postfix_member_offset = 0;
static int postfix_member_size = 0;
+static int postfix_value_is_array = 0;
static int postfix_member_is_floating = 0;
static int postfix_member_is_unsigned = 0;
postfix_member_pointed_size = elem_size;
postfix_member_offset = offset;
postfix_member_size = size;
+ postfix_value_is_array = is_array;
postfix_member_is_floating = is_floating;
postfix_member_is_unsigned = is_unsigned;
postfix_member_calling_convention = last_found_member_calling_convention;
enum token_kind assign_op;
int subscript_elem_size;
+ postfix_value_is_array = 0;
+
if (!is_array && pointer_depth > 0) {
emit_load_member_from_addr_reg_now (reg, reg, offset, DATA_PTR & 0x1f);
} else if (state->ofp && offset != 0) {
}
+static int source_starts_lparen_subscript_call_at (const char *p) {
+
+ int bracket_depth;
+
+ if (!p || *p != '(') {
+ return 0;
+ }
+
+ p++;
+
+ while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
+ p++;
+ }
+
+ if (!((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || *p == '_')) {
+ return 0;
+ }
+
+ p++;
+
+ while ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || (*p >= '0' && *p <= '9') || *p == '_') {
+ p++;
+ }
+
+ while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
+ p++;
+ }
+
+ if (*p != '[') {
+ return 0;
+ }
+
+ bracket_depth = 1;
+ p++;
+
+ while (*p && bracket_depth > 0) {
+
+ if (*p == '[') {
+ bracket_depth++;
+ } else if (*p == ']') {
+ bracket_depth--;
+ }
+
+ p++;
+
+ }
+
+ if (bracket_depth != 0) {
+ return 0;
+ }
+
+ while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
+ p++;
+ }
+
+ if (*p != ')') {
+ return 0;
+ }
+
+ p++;
+
+ while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
+ p++;
+ }
+
+ return *p == '(';
+
+}
+
+static int source_starts_lparen_deref_subscript_call_at (const char *p) {
+
+ int bracket_depth;
+
+ if (!p) {
+ return 0;
+ }
+
+ if (*p == '(') {
+ p++;
+ }
+
+ while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
+ p++;
+ }
+
+ if (*p != '*') {
+ return 0;
+ }
+
+ p++;
+
+ while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
+ p++;
+ }
+
+ if (!((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || *p == '_')) {
+ return 0;
+ }
+
+ p++;
+
+ while ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || (*p >= '0' && *p <= '9') || *p == '_') {
+ p++;
+ }
+
+ while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
+ p++;
+ }
+
+ if (*p != '[') {
+ return 0;
+ }
+
+ bracket_depth = 1;
+ p++;
+
+ while (*p && bracket_depth > 0) {
+
+ if (*p == '[') {
+ bracket_depth++;
+ } else if (*p == ']') {
+ bracket_depth--;
+ }
+
+ p++;
+
+ }
+
+ if (bracket_depth != 0) {
+ return 0;
+ }
+
+ while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
+ p++;
+ }
+
+ if (*p != ')') {
+ return 0;
+ }
+
+ p++;
+
+ while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
+ p++;
+ }
+
+ return *p == '(';
+
+}
+
static int source_starts_lparen_deref_postfix_incdec_at (const char *p) {
if (!p) {
}
+ if (tok.kind == TOK_LPAREN) {
+
+ /*
+ * Subscript parsing leaves reg holding the address of the
+ * selected array element. For an array of function pointers,
+ * load the pointer stored in that element before emitting the
+ * indirect call. Calling reg directly here calls the address
+ * of the array slot instead of the function it contains.
+ */
+ emit_load_deref_reg_now (reg, DATA_PTR & 0x1f);
+
+ emit_call_pointer_in_reg_now (reg, reg);
+ set_rhs_last_pointer_info (0, 0);
+
+ free (name);
+ return;
+
+ }
+
emit_apply_postfix_member_access_to_reg_now (reg);
postfix_copy_lvalue_tag_name = 0;
}
+ if (tok.kind == TOK_LPAREN) {
+
+ /*
+ * Subscript parsing leaves reg holding the address of the
+ * selected array element. For an array of function pointers,
+ * load the pointer stored in that element before emitting the
+ * indirect call. Calling reg directly here calls the address
+ * of the array slot instead of the function it contains.
+ */
+ emit_load_deref_reg_now (reg, DATA_PTR & 0x1f);
+
+ emit_call_pointer_in_reg_now (reg, reg);
+ set_rhs_last_pointer_info (0, 0);
+
+ free (name);
+ return;
+
+ }
+
emit_apply_postfix_member_access_to_reg_now (reg);
postfix_copy_lvalue_tag_name = 0;
if (src->is_array) {
+ postfix_value_is_array = 1;
+
if (src->is_static && src->static_label) {
emit_load_address_to_reg_now (reg, src->static_label);
} else {
if (find_global_symbol (name) >= 0) {
+ postfix_value_is_array = get_global_symbol_array (name);
+
if (get_global_symbol_kind (name) == GLOBAL_SYMBOL_FUNCTION ||
get_global_symbol_array (name) ||
(!get_global_symbol_pointer_depth (name) &&
static void emit_load_assignment_rhs_expression_to_reg (const char *reg);
+static int local_symbol_is_array_now (const struct local_symbol *sym) {
+
+ if (!sym) {
+ return 0;
+ }
+
+ return sym->is_array || sym->array_dimensions > 0 || sym->array_element_size > 0;
+
+}
+
static int current_argument_is_bare_identifier_now (void) {
const char *p;
int offset;
int chunk;
- if (!name || get_global_symbol_kind (name) != GLOBAL_SYMBOL_OBJECT ||
- get_global_symbol_array (name) || get_global_symbol_pointer_depth (name) > 0 ||
- get_global_symbol_floating (name)) {
+ const char *tag_name;
+
+ if (!name) {
+ return 0;
+ }
+
+ if (get_global_symbol_kind (name) != GLOBAL_SYMBOL_OBJECT) {
+ return 0;
+ }
+
+ if (get_global_symbol_array (name)) {
+ return 0;
+ }
+
+ if (get_global_symbol_pointer_depth (name) > 0) {
+ return 0;
+ }
+
+ if (get_global_symbol_floating (name)) {
return 0;
}
size = get_global_symbol_size (name);
+ tag_name = get_global_symbol_tag_name (name);
+
+ /* Only tagged aggregate objects are passed by value here. Untagged
+ * objects include scalar values and arrays whose decay metadata was not
+ * visible during the self-hosting pass; those must use normal expression
+ * loading so arrays decay to one address instead of multiple stack words.
+ */
+ if (!tag_name || !tag_name[0]) {
+ return 0;
+ }
if (size <= (DATA_PTR & 0x1f)) {
return 0;
}
+ postfix_value_is_array = 0;
postfix_member_seen = 0;
postfix_member_size = 0;
postfix_member_pointer_depth = 0;
postfix_member_pointed_size = 0;
- if (tok.kind == TOK_IDENT && tok.ident && current_argument_is_bare_identifier_now () && find_local_symbol (tok.ident) && emit_push_aggregate_argument_now (tok.ident, find_local_symbol (tok.ident))) {
+ if (tok.kind == TOK_IDENT && tok.ident && current_argument_is_bare_identifier_now () && find_local_symbol (tok.ident) && local_symbol_is_array_now (find_local_symbol (tok.ident))) {
+
+ struct local_symbol *arg_sym = find_local_symbol (tok.ident);
+
+ if (arg_sym->is_static && arg_sym->static_label) {
+ emit_load_address_to_reg_now ("eax", arg_sym->static_label);
+ } else {
+ emit_load_local_address_to_reg_now ("eax", arg_sym->offset);
+ }
+
+ emit_push_reg_now ("eax");
+
+ arg_bytes = DATA_PTR & 0x1f;
+ arg_is_floating = 0;
+
+ get_token ();
+
+ } else if (tok.kind == TOK_IDENT && tok.ident && current_argument_is_bare_identifier_now () && find_local_symbol (tok.ident) && emit_push_aggregate_argument_now (tok.ident, find_local_symbol (tok.ident))) {
struct local_symbol *arg_sym = find_local_symbol (tok.ident);
get_token ();
+ } else if (tok.kind == TOK_IDENT && tok.ident && current_argument_is_bare_identifier_now () &&
+ !find_local_symbol (tok.ident) && find_global_symbol (tok.ident) >= 0 &&
+ get_global_symbol_array (tok.ident)) {
+
+ emit_load_address_to_reg_now ("eax", tok.ident);
+ emit_push_reg_now ("eax");
+
+ arg_bytes = DATA_PTR;
+ arg_is_floating = 0;
+
+ get_token ();
+
} else {
int arg_starts_64bit_integer = current_argument_starts_64bit_integer_now ();
emit_push_reg_now ("edx");
emit_push_reg_now ("eax");
- } else if (!arg_is_floating && postfix_member_seen && postfix_member_pointer_depth == 0 && postfix_member_size > (DATA_PTR & 0x1f)) {
+ } else if (!arg_is_floating && postfix_member_seen && postfix_member_pointer_depth == 0 && !postfix_value_is_array && postfix_member_size > (DATA_PTR & 0x1f)) {
arg_bytes = postfix_member_size;
emit_push_aggregate_from_addr_reg_now ("eax", arg_bytes);
- } else if (!arg_is_floating && postfix_member_size > (DATA_PTR & 0x1f)) {
+ } else if (!arg_is_floating && !postfix_value_is_array && postfix_member_size > (DATA_PTR & 0x1f)) {
arg_bytes = postfix_member_size;
emit_push_aggregate_from_addr_reg_now ("eax", arg_bytes);
}
+static int call_argument_expects_by_value_aggregate_now (const char *name, int argument_index) {
+
+ int symbol_index;
+
+ if (!name || argument_index < 0) {
+ return 0;
+ }
+
+ symbol_index = find_global_symbol (name);
+
+ if (symbol_index < 0 || global_symbols[symbol_index].kind != GLOBAL_SYMBOL_FUNCTION || !global_symbols[symbol_index].has_prototype ||
+ argument_index >= global_symbols[symbol_index].param_count ||
+ global_symbols[symbol_index].param_pointer_depths[argument_index] > 0 ||
+ global_symbols[symbol_index].param_floatings[argument_index] ||
+ global_symbols[symbol_index].param_sizes[argument_index] <= (DATA_PTR & 0x1f)) {
+ return 0;
+ }
+
+ return 1;
+
+}
+
static int current_argument_starts_64bit_integer_now (void) {
if (tok.kind == TOK_CLLONG || tok.kind == TOK_CULLONG) {
}
+ postfix_value_is_array = 0;
postfix_member_seen = 0;
postfix_member_size = 0;
postfix_member_pointer_depth = 0;
postfix_member_pointed_size = 0;
- if (!use_inline && tok.kind == TOK_IDENT && tok.ident && current_argument_is_bare_identifier_now () && find_local_symbol (tok.ident) && emit_push_aggregate_argument_now (tok.ident, find_local_symbol (tok.ident))) {
+ if (!use_inline && tok.kind == TOK_IDENT && tok.ident && current_argument_is_bare_identifier_now () && find_local_symbol (tok.ident) && local_symbol_is_array_now (find_local_symbol (tok.ident))) {
+
+ struct local_symbol *arg_sym = find_local_symbol (tok.ident);
+
+ if (arg_sym->is_static && arg_sym->static_label) {
+ emit_load_address_to_reg_now ("eax", arg_sym->static_label);
+ } else {
+ emit_load_local_address_to_reg_now ("eax", arg_sym->offset);
+ }
+
+ emit_push_reg_now ("eax");
+
+ arg_bytes = DATA_PTR & 0x1f;
+ arg_is_floating = 0;
+
+ get_token ();
+
+ } else if (!use_inline && call_argument_expects_by_value_aggregate_now (name, argc) && tok.kind == TOK_IDENT && tok.ident && current_argument_is_bare_identifier_now () && find_local_symbol (tok.ident) && emit_push_aggregate_argument_now (tok.ident, find_local_symbol (tok.ident))) {
struct local_symbol *arg_sym = find_local_symbol (tok.ident);
get_token ();
- } else if (!use_inline && tok.kind == TOK_IDENT && tok.ident && current_argument_is_bare_identifier_now () && !find_local_symbol (tok.ident) && emit_push_global_aggregate_argument_now (tok.ident)) {
+ } else if (!use_inline && tok.kind == TOK_IDENT && tok.ident && current_argument_is_bare_identifier_now () &&
+ !find_local_symbol (tok.ident) && find_global_symbol (tok.ident) >= 0 &&
+ get_global_symbol_array (tok.ident) &&
+ !call_argument_expects_by_value_aggregate_now (name, argc)) {
+
+ emit_load_address_to_reg_now ("eax", tok.ident);
+ emit_push_reg_now ("eax");
+
+ arg_bytes = DATA_PTR;
+ arg_is_floating = 0;
+
+ get_token ();
+
+ } else if (!use_inline && call_argument_expects_by_value_aggregate_now (name, argc) && tok.kind == TOK_IDENT && tok.ident && current_argument_is_bare_identifier_now () && !find_local_symbol (tok.ident) && emit_push_global_aggregate_argument_now (tok.ident)) {
arg_bytes = get_global_symbol_size (tok.ident);
arg_is_floating = 0;
emit_push_reg_now ("edx");
emit_push_reg_now ("eax");
- } else if (!use_inline && !arg_is_floating && postfix_member_seen && postfix_member_pointer_depth == 0 && postfix_member_size > (DATA_PTR & 0x1f)) {
+ } else if (!use_inline && !arg_is_floating && postfix_member_seen && postfix_member_pointer_depth == 0 && !postfix_value_is_array && postfix_member_size > (DATA_PTR & 0x1f)) {
arg_bytes = postfix_member_size;
emit_push_aggregate_from_addr_reg_now ("eax", arg_bytes);
- } else if (!use_inline && !arg_is_floating && postfix_member_size > (DATA_PTR & 0x1f)) {
+ } else if (!use_inline && !arg_is_floating && !postfix_value_is_array && postfix_member_size > (DATA_PTR & 0x1f)) {
arg_bytes = postfix_member_size;
emit_push_aggregate_from_addr_reg_now ("eax", arg_bytes);
}
+ if (tok.kind == TOK_LPAREN) {
+
+ get_token ();
+
+ expect (TOK_RPAREN, ")");
+ emit_call_pointer_in_reg_now ("eax", "eax");
+
+ }
+
emit_load_deref_reg_now ("eax", DATA_PTR & 0x1f);
emit_handle_subscript_after_loaded_pointer_to_reg_now ("eax", pointer_depth - 1, pointed_size, src ? src->pointed_is_unsigned : get_global_symbol_pointed_is_unsigned (name));
emit_parse_postfix_subscript_scaled_address_to_reg_now ("edx", elem_size);
}
+ if (tok.kind == TOK_LPAREN) {
+
+ if (state->ofp) {
+ emit_load_deref_reg_now ("edx", DATA_PTR & 0x1f);
+ }
+
+ emit_call_pointer_in_reg_now ("edx", "eax");
+ expect_semi_or_recover ();
+
+ free (name);
+ return 1;
+
+ }
+
if (tok.kind == TOK_INCR || tok.kind == TOK_DECR) {
op = tok.kind;
const char *base_tag_name = 0;
- if (tok.kind != TOK_LPAREN || !source_starts_with_parenthesized_indirect_call_now ()) {
+ if (tok.kind != TOK_LPAREN || (!source_starts_with_parenthesized_indirect_call_now () && !source_starts_lparen_deref_subscript_call_at (tok.start) && !source_starts_lparen_deref_subscript_call_at (tok.caret) && !source_starts_lparen_subscript_call_at (tok.start) && !source_starts_lparen_subscript_call_at (tok.caret))) {
return 0;
}
get_token ();
- if (tok.kind != TOK_STAR) {
- return 0;
+ if (tok.kind == TOK_STAR) {
+ get_token ();
}
- get_token ();
-
if (tok.kind == TOK_LPAREN) {
wrapped_member_expr = 1;
}
+ if (parse_parenthesized_member_function_pointer_call_statement ()) {
+ return;
+ }
+
if (parse_parenthesized_deref_subscript_statement ()) {
expect_semi_or_recover ();
}
- if (parse_parenthesized_member_function_pointer_call_statement ()) {
- return;
- }
-
if (tok.kind == TOK_LPAREN) {
int parenthesized_assignment_is_unsigned;
}
-static int int64_is_zero_value (int64_s value) {
- return value.low == 0 && value.high == 0;
+static int int64_is_zero_value (const int64_s *value) {
+ return value->low == 0 && value->high == 0;
}
static char masm_pending_data_label[512];
int i;
if (symbols) {
+
for (i = 0; i < value_count; i++) {
+
if (symbols[i]) {
return 0;
}
+
}
+
}
if (!values || value_count <= 0) {
}
for (i = 0; i < value_count; i++) {
- if (!int64_is_zero_value (values[i])) {
+
+ if (!int64_is_zero_value (&values[i])) {
return 0;
}
+
}
return 1;