mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-02 20:18:28 +00:00
winebuild: Generate position-independent code for ARM.
This commit is contained in:
parent
f4985e42b7
commit
4e4acd5f70
2 changed files with 50 additions and 51 deletions
|
@ -650,9 +650,9 @@ static void output_import_thunk( const char *name, const char *table, int pos )
|
||||||
output( "\tjmpq *%s+%d(%%rip)\n", table, pos );
|
output( "\tjmpq *%s+%d(%%rip)\n", table, pos );
|
||||||
break;
|
break;
|
||||||
case CPU_ARM:
|
case CPU_ARM:
|
||||||
output( "\tldr IP,[PC,#0]\n");
|
output( "\tldr IP,1f\n");
|
||||||
output( "\tldr PC,[IP,#%d]\n", pos);
|
output( "\tldr PC,[PC,IP]\n" );
|
||||||
output( "\t.long %s\n", table );
|
output( "1:\t.long %s+%u-(1b+4)\n", table, pos );
|
||||||
break;
|
break;
|
||||||
case CPU_ARM64:
|
case CPU_ARM64:
|
||||||
output( "\tadr x9, 1f\n" );
|
output( "\tadr x9, 1f\n" );
|
||||||
|
@ -967,15 +967,15 @@ static void output_delayed_import_thunks( const DLLSPEC *spec )
|
||||||
output( "\tjmp *%%rax\n" );
|
output( "\tjmp *%%rax\n" );
|
||||||
break;
|
break;
|
||||||
case CPU_ARM:
|
case CPU_ARM:
|
||||||
output( "\tstmfd SP!, {r4-r10,FP,LR}\n" );
|
output( "\tpush {r0-r3,FP,LR}\n" );
|
||||||
output( "\tmov LR,PC\n");
|
output( "\tmov r0,IP\n" );
|
||||||
output( "\tadd LR,LR,#8\n");
|
output( "\tldr IP,2f\n");
|
||||||
output( "\tldr PC,[PC,#-4]\n");
|
output( "\tadd IP,PC\n");
|
||||||
output( "\t.long %s\n", asm_name("__wine_spec_delay_load") );
|
output( "\tblx IP\n");
|
||||||
output( "\tmov IP,r0\n");
|
output( "1:\tmov IP,r0\n");
|
||||||
output( "\tldmfd SP!, {r4-r10,FP,LR}\n" );
|
output( "\tpop {r0-r3,FP,LR}\n" );
|
||||||
output( "\tldmfd SP!, {r0-r3}\n" );
|
output( "\tbx IP\n");
|
||||||
output( "\tmov PC,IP\n");
|
output( "2:\t.long %s-1b\n", asm_name("__wine_spec_delay_load") );
|
||||||
break;
|
break;
|
||||||
case CPU_ARM64:
|
case CPU_ARM64:
|
||||||
output( "\tstp x29, x30, [sp,#-16]!\n" );
|
output( "\tstp x29, x30, [sp,#-16]!\n" );
|
||||||
|
@ -1067,18 +1067,15 @@ static void output_delayed_import_thunks( const DLLSPEC *spec )
|
||||||
output( "\tjmp %s\n", asm_name("__wine_delay_load_asm") );
|
output( "\tjmp %s\n", asm_name("__wine_delay_load_asm") );
|
||||||
break;
|
break;
|
||||||
case CPU_ARM:
|
case CPU_ARM:
|
||||||
output( "\tstmfd SP!, {r0-r3}\n" );
|
{
|
||||||
output( "\tmov r0, #%d\n", idx );
|
unsigned int mask, count = 0, val = (idx << 16) | j;
|
||||||
output( "\tmov r1, #16384\n" );
|
|
||||||
output( "\tmul r1, r0, r1\n" );
|
for (mask = 0xff; mask; mask <<= 8)
|
||||||
output( "\tmov r0, r1\n" );
|
if (val & mask) output( "\t%s IP,#%u\n", count++ ? "add" : "mov", val & mask );
|
||||||
output( "\tmov r1, #4\n" );
|
if (!count) output( "\tmov IP,#0\n" );
|
||||||
output( "\tmul r1, r0, r1\n" );
|
output( "\tb %s\n", asm_name("__wine_delay_load_asm") );
|
||||||
output( "\tmov r0, r1\n" );
|
|
||||||
output( "\tadd r0, #%d\n", j );
|
|
||||||
output( "\tldr PC,[PC,#-4]\n");
|
|
||||||
output( "\t.long %s\n", asm_name("__wine_delay_load_asm") );
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case CPU_ARM64:
|
case CPU_ARM64:
|
||||||
output( "\tstp x6, x7, [sp,#-80]!\n" );
|
output( "\tstp x6, x7, [sp,#-80]!\n" );
|
||||||
output( "\tstp x4, x5, [sp,#48]\n" );
|
output( "\tstp x4, x5, [sp,#48]\n" );
|
||||||
|
@ -1268,19 +1265,19 @@ void output_stubs( DLLSPEC *spec )
|
||||||
output( "\tcall %s\n", asm_name("__wine_spec_unimplemented_stub") );
|
output( "\tcall %s\n", asm_name("__wine_spec_unimplemented_stub") );
|
||||||
break;
|
break;
|
||||||
case CPU_ARM:
|
case CPU_ARM:
|
||||||
output( "\tldr r0,[PC,#0]\n");
|
output( "\tldr r0,2f\n");
|
||||||
output( "\tmov PC,PC\n");
|
output( "\tadd r0,PC\n");
|
||||||
output( "\t.long .L__wine_spec_file_name\n" );
|
output( "\tldr r1,2f+4\n");
|
||||||
output( "\tldr r1,[PC,#0]\n");
|
output( "1:" );
|
||||||
output( "\tmov PC,PC\n");
|
|
||||||
if (exp_name)
|
if (exp_name)
|
||||||
{
|
{
|
||||||
output( "\t.long .L%s_string\n", name );
|
output( "\tadd r1,PC\n");
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
output( "\t.long %d\n", odp->ordinal );
|
|
||||||
output( "\tbl %s\n", asm_name("__wine_spec_unimplemented_stub") );
|
output( "\tbl %s\n", asm_name("__wine_spec_unimplemented_stub") );
|
||||||
|
output( "2:\t.long .L__wine_spec_file_name-1b\n" );
|
||||||
|
if (exp_name) output( "\t.long .L%s_string-2b\n", name );
|
||||||
|
else output( "\t.long %u\n", odp->ordinal );
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
|
@ -210,32 +210,34 @@ static void output_relay_debug( DLLSPEC *spec )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CPU_ARM:
|
case CPU_ARM:
|
||||||
switch (args)
|
{
|
||||||
|
unsigned int mask, val, count = 0;
|
||||||
|
unsigned int stack_size = min( 16, (args * 4 + 7) & ~7 );
|
||||||
|
|
||||||
|
if (odp->flags & FLAG_RET64) flags |= 1;
|
||||||
|
val = (flags << 24) | (args << 16) | (i - spec->base);
|
||||||
|
switch (stack_size)
|
||||||
{
|
{
|
||||||
default: output( "\tpush {r0-r3}\n" ); break;
|
case 16: output( "\tpush {r0-r3}\n" ); break;
|
||||||
case 3: output( "\tpush {r0-r2}\n" ); break;
|
case 8: output( "\tpush {r0-r1}\n" ); break;
|
||||||
case 2: output( "\tpush {r0-r1}\n" ); break;
|
|
||||||
case 1: output( "\tpush {r0}\n" ); break;
|
|
||||||
case 0: break;
|
case 0: break;
|
||||||
}
|
}
|
||||||
output( "\tpush {LR}\n" );
|
output( "\tpush {LR}\n" );
|
||||||
output( "\tmov r2, SP\n");
|
output( "\tmov r2, SP\n");
|
||||||
if (odp->flags & FLAG_RET64) flags |= 1;
|
output( "\tsub SP, #4\n");
|
||||||
output( "\tmov r1, #%u\n", (flags << 24) );
|
for (mask = 0xff; mask; mask <<= 8)
|
||||||
if (args) output( "\tadd r1, #%u\n", (args << 16) );
|
if (val & mask) output( "\t%s r1,#%u\n", count++ ? "add" : "mov", val & mask );
|
||||||
if ((i - spec->base) & 0xf000) output( "\tadd r1, #%u\n", (i - spec->base) & 0xf000 );
|
if (!count) output( "\tmov r1,#0\n" );
|
||||||
if ((i - spec->base) & 0x0f00) output( "\tadd r1, #%u\n", (i - spec->base) & 0x0f00 );
|
output( "\tldr r0, 2f\n");
|
||||||
if ((i - spec->base) & 0x00f0) output( "\tadd r1, #%u\n", (i - spec->base) & 0x00f0 );
|
output( "\tadd r0, PC\n");
|
||||||
if ((i - spec->base) & 0x000f) output( "\tadd r1, #%u\n", (i - spec->base) & 0x000f );
|
output( "\tldr IP, [r0, #4]\n");
|
||||||
output( "\tldr r0, [PC, #0]\n");
|
output( "1:\tblx IP\n");
|
||||||
output( "\tmov PC, PC\n");
|
output( "\tldr IP, [SP, #4]\n" );
|
||||||
output( "\t.long .L__wine_spec_relay_descr\n" );
|
output( "\tadd SP, #%u\n", stack_size + 8 );
|
||||||
output( "\tldr r3, [r0, #4]\n");
|
output( "\tbx IP\n");
|
||||||
output( "\tblx r3\n");
|
output( "2:\t.long .L__wine_spec_relay_descr-1b\n" );
|
||||||
output( "\tpop {r3}\n" );
|
|
||||||
if (args) output( "\tadd SP, SP, #%u\n", min(args*4, 16) );
|
|
||||||
output( "\tbx r3\n");
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case CPU_x86_64:
|
case CPU_x86_64:
|
||||||
output( "\tsubq $40,%%rsp\n" );
|
output( "\tsubq $40,%%rsp\n" );
|
||||||
|
|
Loading…
Reference in a new issue