return;
}
- if (state->ofp) {
+ {
- if (state->syntax & ASM_SYNTAX_INTEL) {
+ int return_pointer = get_global_symbol_pointer_depth (name) > 0;
+ int return_size = return_pointer ? (DATA_PTR & 0x1f) : get_global_symbol_size (name);
+ int return_unsigned = return_pointer ? 1 : get_global_symbol_unsigned (name);
- if (strcmp (lo, "rax") != 0) {
- fprintf (state->ofp, " mov %s, rax\n", lo);
- }
-
- if (strcmp (hi, "rdx") != 0) {
- fprintf (state->ofp, " mov %s, rdx\n", hi);
- }
+ const char *qlo = amd64_qword_reg_name_from_any (lo);
+ const char *dlo = amd64_dword_reg_name_from_any (lo);
+ const char *qhi = amd64_qword_reg_name_from_any (hi);
- } else {
+ if (state->ofp) {
- if (strcmp (lo, "rax") != 0) {
- fprintf (state->ofp, " movq %%rax, %%%s\n", lo);
- }
+ if (state->syntax & ASM_SYNTAX_INTEL) {
+
+ if (return_size == (DATA_LLONG & 0x1f) || return_pointer) {
+
+ if (strcmp (qlo, "rax") != 0) {
+ fprintf (state->ofp, " mov %s, rax\n", qlo);
+ }
+
+ } else if (return_size == (DATA_CHAR & 0x1f)) {
+
+ if (return_unsigned) {
+ fprintf (state->ofp, " movzx %s, al\n", dlo);
+ } else {
+ fprintf (state->ofp, " movsx %s, al\n", qlo);
+ }
+
+ } else if (return_size == (DATA_SHORT & 0x1f)) {
+
+ if (return_unsigned) {
+ fprintf (state->ofp, " movzx %s, ax\n", dlo);
+ } else {
+ fprintf (state->ofp, " movsx %s, ax\n", qlo);
+ }
+
+ } else {
+
+ if (return_unsigned) {
+
+ if (strcmp (dlo, "eax") != 0) {
+ fprintf (state->ofp, " mov %s, eax\n", dlo);
+ }
+
+ } else {
+ fprintf (state->ofp, " movsxd %s, eax\n", qlo);
+ }
+
+ }
+
+ fprintf (state->ofp, " xor %s, %s\n", qhi, qhi);
+
+ } else {
+
+ if (return_size == (DATA_LLONG & 0x1f) || return_pointer) {
+
+ if (strcmp (qlo, "rax") != 0) {
+ fprintf (state->ofp, " movq %%rax, %%%s\n", qlo);
+ }
+
+ } else if (return_size == (DATA_CHAR & 0x1f)) {
+
+ if (return_unsigned) {
+ fprintf (state->ofp, " movzbl %%al, %%%s\n", dlo);
+ } else {
+ fprintf (state->ofp, " movsbq %%al, %%%s\n", qlo);
+ }
+
+ } else if (return_size == (DATA_SHORT & 0x1f)) {
+
+ if (return_unsigned) {
+ fprintf (state->ofp, " movzwl %%ax, %%%s\n", dlo);
+ } else {
+ fprintf (state->ofp, " movswq %%ax, %%%s\n", qlo);
+ }
+
+ } else {
+
+ if (return_unsigned) {
+
+ if (strcmp (dlo, "eax") != 0) {
+ fprintf (state->ofp, " movl %%eax, %%%s\n", dlo);
+ }
+
+ } else {
+ fprintf (state->ofp, " movslq %%eax, %%%s\n", qlo);
+ }
+
+ }
+
+ fprintf (state->ofp, " xorq %%%s, %%%s\n", qhi, qhi);
- if (strcmp (hi, "rdx") != 0) {
- fprintf (state->ofp, " movq %%rdx, %%%s\n", hi);
}
}
}
emit_load_assignment_rhs_expression_to_reg (lo);
+
+ if (rhs_last_pointer_depth > 1) {
+
+ deref_size = DATA_PTR & 0x1f;
+ deref_unsigned = 1;
+
+ } else if (rhs_last_pointer_depth == 1) {
+
+ deref_size = rhs_last_pointed_size > 0 ? rhs_last_pointed_size : (DATA_INT & 0x1f);
+ deref_unsigned = rhs_last_scalar_is_unsigned >= 0 ? rhs_last_scalar_is_unsigned : 0;
+
+ }
+
expect (TOK_RPAREN, ")");
- emit_load_deref_reg_now (lo, DATA_INT & 0x1f);
- emit_extend_pair_high_from_low (lo, hi, DATA_INT & 0x1f, 1);
+ emit_load_deref_reg_ex_now (lo, deref_size, deref_unsigned);
+ emit_extend_pair_high_from_low (lo, hi, deref_size, deref_unsigned);
return;
return;
}
- if (state->ofp) {
+ {
- if (state->syntax & ASM_SYNTAX_INTEL) {
+ int return_size = get_global_symbol_pointer_depth (name) > 0 ? (DATA_PTR & 0x1f) : get_global_symbol_size (name);
+ int return_unsigned = get_global_symbol_pointer_depth (name) > 0 ? 1 : get_global_symbol_unsigned (name);
- if (strcmp (lo, "eax") != 0) {
- fprintf (state->ofp, " mov %s, eax\n", lo);
- }
+ if ((return_size & 0x1f) == (DATA_LLONG & 0x1f)) {
+
+ if (state->ofp) {
+
+ if (state->syntax & ASM_SYNTAX_INTEL) {
+
+ if (strcmp (lo, "eax") != 0) {
+ fprintf (state->ofp, " mov %s, eax\n", lo);
+ }
+
+ if (strcmp (hi, "edx") != 0) {
+ fprintf (state->ofp, " mov %s, edx\n", hi);
+ }
+
+ } else {
+
+ if (strcmp (lo, "eax") != 0) {
+ fprintf (state->ofp, " movl %%eax, %%%s\n", lo);
+ }
+
+ if (strcmp (hi, "edx") != 0) {
+ fprintf (state->ofp, " movl %%edx, %%%s\n", hi);
+ }
+
+ }
- if (strcmp (hi, "edx") != 0) {
- fprintf (state->ofp, " mov %s, edx\n", hi);
}
} else {
- if (strcmp (lo, "eax") != 0) {
- fprintf (state->ofp, " movl %%eax, %%%s\n", lo);
- }
+ if (strcmp (lo, "eax") != 0 && state->ofp) {
+
+ if (state->syntax & ASM_SYNTAX_INTEL) {
+ fprintf (state->ofp, " mov %s, eax\n", lo);
+ } else {
+ fprintf (state->ofp, " movl %%eax, %%%s\n", lo);
+ }
- if (strcmp (hi, "edx") != 0) {
- fprintf (state->ofp, " movl %%edx, %%%s\n", hi);
}
+
+ emit_extend_pair_high_from_low (lo, hi, return_size, return_unsigned);
}