winebuild: Simplify constant loading on ARM.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-02-24 10:38:50 +01:00
parent b1fe783ade
commit abf4747ba7
2 changed files with 34 additions and 29 deletions

View File

@ -1166,23 +1166,15 @@ static void output_delayed_import_thunks( const DLLSPEC *spec )
switch(target_cpu)
{
case CPU_x86:
output( "\tmovl $%d, %%eax\n", (idx << 16) | j );
output( "\tjmp %s\n", asm_name("__wine_delay_load_asm") );
break;
case CPU_x86_64:
output( "\tmovq $%d,%%rax\n", (idx << 16) | j );
output( "\tmovl $%d,%%eax\n", (idx << 16) | j );
output( "\tjmp %s\n", asm_name("__wine_delay_load_asm") );
break;
case CPU_ARM:
{
unsigned int mask, count = 0, val = (idx << 16) | j;
for (mask = 0xff; mask; mask <<= 8)
if (val & mask) output( "\t%s IP,#%u\n", count++ ? "add" : "mov", val & mask );
if (!count) output( "\tmov IP,#0\n" );
output( "\tmov ip, #%u\n", j );
if (idx) output( "\tmovt ip, #%u\n", idx );
output( "\tb %s\n", asm_name("__wine_delay_load_asm") );
break;
}
case CPU_ARM64:
if (idx)
{
@ -1370,12 +1362,15 @@ void output_stubs( DLLSPEC *spec )
}
else
{
output( "\tldr r0,1f\n");
output( "\tldr r1,1f+4\n");
output( "\tmovw r0,:lower16:.L__wine_spec_file_name\n");
output( "\tmovt r0,:upper16:.L__wine_spec_file_name\n");
if (exp_name)
{
output( "\tmovw r1,:lower16:.L%s_string\n", name );
output( "\tmovt r1,:upper16:.L%s_string\n", name );
}
else output( "\tmov r1,#%u\n", odp->ordinal );
output( "\tbl %s\n", asm_name("__wine_spec_unimplemented_stub") );
output( "1:\t.long .L__wine_spec_file_name\n" );
if (exp_name) output( "\t.long .L%s_string\n", name );
else output( "\t.long %u\n", odp->ordinal );
}
break;
case CPU_ARM64:
@ -1823,15 +1818,21 @@ void output_syscalls( DLLSPEC *spec )
break;
case CPU_ARM:
output( "\tpush {r4,lr}\n" );
output( "\tldr r4, 3f\n");
output( "\tldr ip, 2f\n");
if (UsePIC) output( "1:\tadd ip, pc\n" );
output( "\tmov r4, #%u\n", i );
if (UsePIC)
{
output( "\tldr ip, 2f\n");
output( "1:\tadd ip, pc\n" );
}
else
{
output( "\tmovw ip, :lower16:%s\n", asm_name("__wine_syscall_dispatcher") );
output( "\tmovt ip, :upper16:%s\n", asm_name("__wine_syscall_dispatcher") );
}
output( "\tldr ip, [ip]\n");
output( "\tblx ip\n");
output( "\tpop {r4,pc}\n" );
if (UsePIC) output( "2:\t.long %s-1b-%u\n", asm_name("__wine_syscall_dispatcher"), thumb_mode ? 4 : 8 );
else output( "2:\t.long %s\n", asm_name("__wine_syscall_dispatcher") );
output( "3:\t.long %u\n", i );
break;
case CPU_ARM64:
output( "\tstp x29, x30, [sp,#-16]!\n" );

View File

@ -297,14 +297,12 @@ static void output_relay_debug( DLLSPEC *spec )
case CPU_ARM:
{
unsigned int mask, val, count = 0;
int j, has_float = 0;
if (strcmp( float_abi_option, "soft" ))
for (j = 0; j < odp->u.func.nb_args && !has_float; j++)
has_float = is_float_arg( odp, j );
val = (odp->u.func.args_str_offset << 16) | (i - spec->base);
output( "\t.align %d\n", get_alignment(4) );
if (thumb_mode) output( "\t.thumb_func\n" );
output( "__wine_spec_relay_entry_point_%d:\n", i );
@ -314,18 +312,24 @@ static void output_relay_debug( DLLSPEC *spec )
if (has_float) output( "\tvpush {s0-s15}\n" );
output( "\tpush {LR}\n" );
output( "\tsub SP, #4\n");
for (mask = 0xff; mask; mask <<= 8)
if (val & mask) output( "\t%s r1,#%u\n", count++ ? "add" : "mov", val & mask );
if (!count) output( "\tmov r1,#0\n" );
output( "\tldr r0, 2f\n");
if (UsePIC) output( "1:\tadd r0, PC\n");
output( "\tmov r1,#%u\n", i - spec->base );
output( "\tmovt r1,#%u\n", odp->u.func.args_str_offset );
if (UsePIC)
{
output( "\tldr r0, 2f\n");
output( "1:\tadd r0, PC\n");
}
else
{
output( "\tmovw r0, :lower16:.L__wine_spec_relay_descr\n" );
output( "\tmovt r0, :upper16:.L__wine_spec_relay_descr\n" );
}
output( "\tldr IP, [r0, #4]\n");
output( "\tblx IP\n");
output( "\tldr IP, [SP, #4]\n" );
output( "\tadd SP, #%u\n", 24 + (has_float ? 64 : 0) );
output( "\tbx IP\n");
if (UsePIC) output( "2:\t.long .L__wine_spec_relay_descr-1b-%u\n", thumb_mode ? 4 : 8 );
else output( "2:\t.long .L__wine_spec_relay_descr\n" );
output_cfi( ".cfi_endproc" );
break;
}