int pointer_depth;
int pointed_size;
int pointed_is_floating;
+ int pointed_is_unsigned;
int returns_void;
int param_count;
global_symbols[i].pointed_size = pointed_size;
global_symbols[i].pointed_is_floating = pointer_depth > 0 ? (parsed_type_is_floating ? 1 : 0) : 0;
+ global_symbols[i].pointed_is_unsigned = pointer_depth > 0 ? (parsed_type_is_unsigned ? 1 : 0) : 0;
}
}
+static int get_global_symbol_pointed_is_unsigned (const char *name) {
+
+ int i = find_global_symbol (name);
+
+ if (i >= 0) {
+ return global_symbols[i].pointed_is_unsigned;
+ }
+
+ return 0;
+
+}
+
static void set_global_symbol_tag_name (const char *name, const char *tag_name) {
int i = find_global_symbol (name);
global_symbols[global_symbol_count].is_unsigned = 0;
global_symbols[global_symbol_count].is_floating = 0;
global_symbols[global_symbol_count].is_array = 0;
+ global_symbols[global_symbol_count].pointer_depth = 0;
+ global_symbols[global_symbol_count].pointed_size = 0;
+ global_symbols[global_symbol_count].pointed_is_floating = 0;
+ global_symbols[global_symbol_count].pointed_is_unsigned = 0;
global_symbols[global_symbol_count].returns_void = 0;
{
int pointer_depth;
int pointed_size;
int pointed_is_floating;
+ int pointed_is_unsigned;
char *pointed_tag_name;
char *tag_name;
local_symbols[local_symbol_count].pointer_depth = 0;
local_symbols[local_symbol_count].pointed_size = 0;
local_symbols[local_symbol_count].pointed_is_floating = 0;
+ local_symbols[local_symbol_count].pointed_is_unsigned = 0;
local_symbols[local_symbol_count].pointed_tag_name = 0;
local_symbols[local_symbol_count].tag_name = 0;
local_symbols[local_symbol_count].pointer_depth = 0;
local_symbols[local_symbol_count].pointed_size = 0;
local_symbols[local_symbol_count].pointed_is_floating = 0;
+ local_symbols[local_symbol_count].pointed_is_unsigned = 0;
local_symbols[local_symbol_count].pointed_tag_name = 0;
local_symbols[local_symbol_count].tag_name = 0;
int pointer_depth;
int pointed_size;
int pointed_is_floating;
+ int pointed_is_unsigned;
char *pointed_tag_name;
pending_params[i].is_floating = 0;
pending_params[i].pointer_depth = 0;
pending_params[i].pointed_size = 0;
+ pending_params[i].pointed_is_floating = 0;
+ pending_params[i].pointed_is_unsigned = 0;
if (pending_params[i].pointed_tag_name) {
}
-static void add_pending_param (const char *name, int size, int align, int is_unsigned, int is_floating, int pointer_depth, int pointed_size) {
+static void add_pending_param (const char *name, int size, int align, int is_unsigned, int is_floating, int pointer_depth, int pointed_size, int pointed_is_unsigned) {
if (pointer_depth > 0 && parsed_type_is_aggregate && parsed_type_size > (DATA_PTR & 0x1f) && pointed_size <= (DATA_PTR & 0x1f)) {
pointed_size = parsed_type_size;
pending_params[pending_param_count].pointer_depth = pointer_depth;
pending_params[pending_param_count].pointed_size = pointed_size > 0 ? pointed_size : 0;
pending_params[pending_param_count].pointed_is_floating = pointer_depth > 0 ? (parsed_type_is_floating ? 1 : 0) : 0;
+ pending_params[pending_param_count].pointed_is_unsigned = pointer_depth > 0 ? (pointed_is_unsigned ? 1 : 0) : 0;
pending_params[pending_param_count].pointed_tag_name = (pointer_depth > 0 && parsed_type_tag_name[0]) ? xstrdup (parsed_type_tag_name) : 0;
pending_param_count++;
return find_pending_param_from (name, 0);
}
-static void update_pending_param (const char *name, int size, int align, int is_unsigned, int is_floating, int pointer_depth, int pointed_size) {
+static void update_pending_param (const char *name, int size, int align, int is_unsigned, int is_floating, int pointer_depth, int pointed_size, int pointed_is_unsigned) {
int i = find_pending_param (name);
pending_params[i].pointer_depth = pointer_depth;
pending_params[i].pointed_size = pointed_size > 0 ? pointed_size : 0;
pending_params[i].pointed_is_floating = pointer_depth > 0 ? (parsed_type_is_floating ? 1 : 0) : 0;
+ pending_params[i].pointed_is_unsigned = pointer_depth > 0 ? (pointed_is_unsigned ? 1 : 0) : 0;
if (pending_params[i].pointed_tag_name) {
sym->pointed_size = pointed_size;
sym->pointed_is_floating = pointer_depth > 0 ? (parsed_type_is_floating ? 1 : 0) : 0;
+ sym->pointed_is_unsigned = pointer_depth > 0 ? (parsed_type_is_unsigned ? 1 : 0) : 0;
if (sym->pointed_tag_name) {
local_symbols[local_symbol_count].is_floating = pending_params[i].is_floating;
local_symbols[local_symbol_count].pointer_depth = pending_params[i].pointer_depth;
local_symbols[local_symbol_count].pointed_is_floating = pending_params[i].pointed_is_floating;
+ local_symbols[local_symbol_count].pointed_is_unsigned = pending_params[i].pointed_is_unsigned;
local_symbols[local_symbol_count].is_array = 0;
local_symbols[local_symbol_count].array_element_size = 0;
local_symbols[local_symbol_count].array_dimensions = 0;
add_pending_param (param_name, param_size, type_alignment (param_size),
(declarator_is_pointer || parsed_type_is_array_typedef ? 0 : parsed_type_is_unsigned),
(declarator_is_pointer || declarator_has_array || declarator_has_function || parsed_type_is_array_typedef) ? 0 : parsed_type_is_floating,
- declarator_pointer_depth, parsed_type_is_aggregate ? parsed_type_size : (parsed_type_size & 0x1f));
+ declarator_pointer_depth, parsed_type_is_aggregate ? parsed_type_size : (parsed_type_size & 0x1f), parsed_type_is_unsigned);
}
if (find_pending_param_from (param_name, old_style_param_start) >= 0) {
report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "duplicate parameter '%s'", param_name);
} else {
- add_pending_param (param_name, param_size, type_alignment (param_size), 0, 0, unknown_typedef_pointer ? 1 : 0, DATA_INT & 0x1f);
+ add_pending_param (param_name, param_size, type_alignment (param_size), 0, 0, unknown_typedef_pointer ? 1 : 0, DATA_INT & 0x1f, 0);
}
}
if (find_pending_param_from (maybe_type_name, old_style_param_start) >= 0) {
report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "duplicate parameter '%s'", maybe_type_name);
} else {
- add_pending_param (maybe_type_name, DATA_INT & 0x1f, type_alignment (DATA_INT & 0x1f), 0, 0, 0, 0);
+ add_pending_param (maybe_type_name, DATA_INT & 0x1f, type_alignment (DATA_INT & 0x1f), 0, 0, 0, 0, 0);
}
}
update_pending_param (name, param_size, type_alignment (param_size),
(declarator_is_pointer || declarator_has_array || declarator_has_function || parsed_type_is_array_typedef ? 0 : parsed_type_is_unsigned),
(declarator_is_pointer || declarator_has_array || declarator_has_function || parsed_type_is_array_typedef ? 0 : parsed_type_is_floating),
- param_pointer_depth, parsed_type_is_aggregate ? parsed_type_size : (parsed_type_size & 0x1f));
+ param_pointer_depth, parsed_type_is_aggregate ? parsed_type_size : (parsed_type_size & 0x1f), parsed_type_is_unsigned);
free (name);
}
+static void emit_load_deref_reg_ex_now (const char *reg, int size, int is_unsigned);
static void emit_load_deref_reg_now (const char *reg, int size);
static int emit_load_parenthesized_indirect_member_to_reg_now (const char *reg);
static int emit_parse_postfix_copy_source_address_now (const char *reg, struct local_symbol *src, const char *src_name, const char *name_start, const char *name_caret, unsigned long name_line);
-static void emit_load_postfix_lvalue_address_to_pair_now (const char *lo, const char *hi, int size) {
+static void emit_load_postfix_lvalue_address_to_pair_ex_now (const char *lo, const char *hi, int size, int is_unsigned) {
if (!state->ofp) {
return;
} else {
- emit_load_deref_reg_now (lo, size);
+ emit_load_deref_reg_ex_now (lo, size, is_unsigned);
if (state->syntax & ASM_SYNTAX_INTEL) {
fprintf (state->ofp, " xor %s, %s\n", hi, hi);
}
- emit_load_postfix_lvalue_address_to_pair_now (lo, hi, source_size);
+ emit_load_postfix_lvalue_address_to_pair_ex_now (lo, hi, source_size, src ? (src->pointer_depth > 0 ? src->pointed_is_unsigned : src->is_unsigned) : (get_global_symbol_pointer_depth (name) > 0 ? get_global_symbol_pointed_is_unsigned (name) : get_global_symbol_unsigned (name)));
free (name);
return;
}
-static void emit_load_deref_reg_now (const char *reg, int size) {
+static void emit_load_deref_reg_ex_now (const char *reg, int size, int is_unsigned) {
+ const char *op8;
+ const char *op16;
+
if (!state->ofp) {
return;
}
+ op8 = is_unsigned ? "movzx" : "movsx";
+ op16 = is_unsigned ? "movzx" : "movsx";
+
if (state->syntax & ASM_SYNTAX_INTEL) {
if (state->syntax & ASM_SYNTAX_NASM) {
if (size == (DATA_CHAR & 0x1f)) {
- fprintf (state->ofp, " movsx %s, byte [%s]\n", reg, reg);
+ fprintf (state->ofp, " %s %s, byte [%s]\n", op8, reg, reg);
} else if (size == (DATA_SHORT & 0x1f)) {
- fprintf (state->ofp, " movsx %s, word [%s]\n", reg, reg);
+ fprintf (state->ofp, " %s %s, word [%s]\n", op16, reg, reg);
} else {
fprintf (state->ofp, " mov %s, dword [%s]\n", reg, reg);
}
} else {
if (size == (DATA_CHAR & 0x1f)) {
- fprintf (state->ofp, " movsx %s, byte ptr [%s]\n", reg, reg);
+ fprintf (state->ofp, " %s %s, byte ptr [%s]\n", op8, reg, reg);
} else if (size == (DATA_SHORT & 0x1f)) {
- fprintf (state->ofp, " movsx %s, word ptr [%s]\n", reg, reg);
+ fprintf (state->ofp, " %s %s, word ptr [%s]\n", op16, reg, reg);
} else {
fprintf (state->ofp, " mov %s, dword ptr [%s]\n", reg, reg);
}
} else {
if (size == (DATA_CHAR & 0x1f)) {
- fprintf (state->ofp, " movsbl (%%%s), %%%s\n", reg, reg);
+ fprintf (state->ofp, " %s (%%%s), %%%s\n", is_unsigned ? "movzbl" : "movsbl", reg, reg);
} else if (size == (DATA_SHORT & 0x1f)) {
- fprintf (state->ofp, " movswl (%%%s), %%%s\n", reg, reg);
+ fprintf (state->ofp, " %s (%%%s), %%%s\n", is_unsigned ? "movzwl" : "movswl", reg, reg);
} else {
fprintf (state->ofp, " movl (%%%s), %%%s\n", reg, reg);
}
}
+static void emit_load_deref_reg_now (const char *reg, int size) {
+ emit_load_deref_reg_ex_now (reg, size, 0);
+}
+
static void emit_store_reg_to_deref_reg_now (const char *addr_reg, const char *value_reg, int size) {
if (suppress_next_struct_return_scalar_store) {
}
-static int emit_handle_subscript_after_loaded_pointer_to_reg_now (const char *reg, int pointer_depth, int pointed_size) {
+static int emit_handle_subscript_after_loaded_pointer_to_reg_now (const char *reg, int pointer_depth, int pointed_size, int pointed_is_unsigned) {
int subscript_elem_size;
}
- emit_load_deref_reg_now (reg, subscript_elem_size);
+ emit_load_deref_reg_ex_now (reg, subscript_elem_size, pointer_depth <= 1 ? pointed_is_unsigned : 0);
if (pointer_depth > 1) {
set_rhs_last_pointer_info (pointer_depth - 1, pointed_size);
clear_rhs_last_pointer_info ();
}
- if (emit_handle_subscript_after_loaded_pointer_to_reg_now (reg, lhs_sym->pointer_depth > 0 ? lhs_sym->pointer_depth - 1 : 0, lhs_sym->pointed_size)) {
+ if (emit_handle_subscript_after_loaded_pointer_to_reg_now (reg, lhs_sym->pointer_depth > 0 ? lhs_sym->pointer_depth - 1 : 0, lhs_sym->pointed_size, lhs_sym->pointed_is_unsigned)) {
free (lhs_name);
return;
if (lhs_has_postfix) {
emit_push_reg_now (reg);
+
emit_incdec_symbol_now (0, lhs_name, lhs_postfix_op, lhs_line, lhs_start, lhs_caret);
emit_pop_reg_now (reg);
clear_rhs_last_pointer_info ();
}
- if (emit_handle_subscript_after_loaded_pointer_to_reg_now (reg, get_global_symbol_pointer_depth (lhs_name) > 0 ? get_global_symbol_pointer_depth (lhs_name) - 1 : 0, get_global_symbol_pointed_size (lhs_name))) {
+ if (emit_handle_subscript_after_loaded_pointer_to_reg_now (reg, get_global_symbol_pointer_depth (lhs_name) > 0 ? get_global_symbol_pointer_depth (lhs_name) - 1 : 0, get_global_symbol_pointed_size (lhs_name), get_global_symbol_pointed_is_unsigned (lhs_name))) {
free (lhs_name);
return;
emit_load_local_to_reg (reg, src->offset, DATA_PTR);
}
- saw_subscript = emit_parse_postfix_subscripts_to_reg_dims_now (reg, elem_size, src->pointer_depth, src->pointed_size, src->array_dimensions, src->is_unsigned);
+ saw_subscript = emit_parse_postfix_subscripts_to_reg_dims_now (reg, elem_size, src->pointer_depth, src->pointed_size, src->array_dimensions, src->pointer_depth > 0 ? src->pointed_is_unsigned : src->is_unsigned);
postfix_copy_lvalue_size = index_step_size (elem_size);
postfix_copy_lvalue_tag_name = src->is_array ? (src->tag_name ? src->tag_name : src->pointed_tag_name) : src->pointed_tag_name;
emit_load_global_to_reg (reg, name, DATA_PTR);
}
- saw_subscript = emit_parse_postfix_subscripts_to_reg_dims_now (reg, elem_size, get_global_symbol_pointer_depth (name), get_global_symbol_pointed_size (name), get_global_symbol_array_dimensions (name), get_global_symbol_unsigned (name));
+ saw_subscript = emit_parse_postfix_subscripts_to_reg_dims_now (reg, elem_size, get_global_symbol_pointer_depth (name), get_global_symbol_pointed_size (name), get_global_symbol_array_dimensions (name), get_global_symbol_pointer_depth (name) > 0 ? get_global_symbol_pointed_is_unsigned (name) : get_global_symbol_unsigned (name));
postfix_copy_lvalue_size = index_step_size (elem_size);
postfix_copy_lvalue_tag_name = get_global_symbol_array (name) ? get_global_symbol_tag_name (name) : 0;
}
+static int current_argument_is_bare_64bit_identifier_now (void) {
+
+ struct local_symbol *sym;
+
+ if (tok.kind != TOK_IDENT || !tok.ident || !current_argument_is_bare_identifier_now ()) {
+ return 0;
+ }
+
+ sym = find_local_symbol (tok.ident);
+
+ if (sym) {
+ return sym->size == (DATA_LLONG & 0x1f) && !sym->is_floating;
+ }
+
+ if (find_global_symbol (tok.ident) >= 0) {
+ return get_global_symbol_size (tok.ident) == (DATA_LLONG & 0x1f) && !get_global_symbol_floating (tok.ident);
+ }
+
+ return 0;
+
+}
+
static void emit_call_identifier_to_reg_now (const char *name, const char *reg, const char *name_start, const char *name_caret, unsigned long name_line) {
int argc = 0;
emit_load_assignment_rhs_expression_to_pair ("eax", "edx", get_global_symbol_param_unsigned (name, argc));
+ } else if (!use_inline && get_global_symbol_has_prototype (name) && get_global_symbol_is_variadic (name) && argc >= get_global_symbol_param_count (name) && current_argument_is_bare_64bit_identifier_now ()) {
+
+ arg_is_floating = 0;
+ arg_bytes = DATA_LLONG & 0x1f;
+
+ emit_load_assignment_rhs_expression_to_pair ("eax", "edx", rhs_current_operand_is_unsigned_now ());
+
} else if (arg_is_floating) {
emit_load_floating_rhs_expression_now (DATA_DOUBLE & 0x1f);
} else {
}
emit_load_deref_reg_now ("eax", DATA_PTR & 0x1f);
- emit_handle_subscript_after_loaded_pointer_to_reg_now ("eax", pointer_depth - 1, pointed_size);
+ 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));
free (name);
return 1;
add_pending_param (param_name, param_size, type_alignment (param_size),
(declarator_is_pointer || declarator_has_array || declarator_has_function || parsed_type_is_array_typedef ? 0 : parsed_type_is_unsigned),
(declarator_is_pointer || declarator_has_array || declarator_has_function || parsed_type_is_array_typedef ? 0 : parsed_type_is_floating),
- param_pointer_depth, parsed_type_is_aggregate ? parsed_type_size : (parsed_type_size & 0x1f));
+ param_pointer_depth, parsed_type_is_aggregate ? parsed_type_size : (parsed_type_size & 0x1f), parsed_type_is_unsigned);
}
report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "duplicate parameter '%s'", tok.ident);
} else {
- add_pending_param (tok.ident, DATA_INT & 0x1f, type_alignment (DATA_INT & 0x1f), 0, 0, 0, 0);
+ add_pending_param (tok.ident, DATA_INT & 0x1f, type_alignment (DATA_INT & 0x1f), 0, 0, 0, 0, 0);
declarator_function_param_count++;
}