Commit 2c1b35dd authored by Vincent Béron's avatar Vincent Béron Committed by Alexandre Julliard

Add some more Alpha asm code and Alpha-specific parts.

parent 5736111c
......@@ -70,6 +70,8 @@ static CRITICAL_SECTION vectored_handlers_section = { &critsect_debug, -1, 0, 0,
# define GET_IP(context) ((LPVOID)(context)->pc)
#elif defined(__powerpc__)
# define GET_IP(context) ((LPVOID)(context)->Iar)
#elif defined(__ALPHA__)
# define GET_IP(context) ((LPVOID)(context)->Fir)
#else
# error You must define GET_IP for this CPU
#endif
......
......@@ -249,11 +249,11 @@ long interlocked_xchg_add( long *dest, long incr )
__ASM_GLOBAL_FUNC(interlocked_cmpxchg,
"L0cmpxchg:\n\t"
"ldq_l $0,0($16)\n\t"
"ldl_l $0,0($16)\n\t"
"cmpeq $0,$18,$1\n\t"
"beq $1,L1cmpxchg\n\t"
"mov $17,$0\n\t"
"stq_c $0,0($16)\n\t"
"stl_c $0,0($16)\n\t"
"beq $0,L0cmpxchg\n\t"
"mov $18,$0\n"
"L1cmpxchg:\n\t"
......@@ -273,9 +273,9 @@ __ASM_GLOBAL_FUNC(interlocked_cmpxchg_ptr,
__ASM_GLOBAL_FUNC(interlocked_xchg,
"L0xchg:\n\t"
"ldq_l $0,0($16)\n\t"
"ldl_l $0,0($16)\n\t"
"mov $17,$1\n\t"
"stq_c $1,0($16)\n\t"
"stl_c $1,0($16)\n\t"
"beq $1,L0xchg\n\t"
"mb");
......@@ -289,9 +289,9 @@ __ASM_GLOBAL_FUNC(interlocked_xchg_ptr,
__ASM_GLOBAL_FUNC(interlocked_xchg_add,
"L0xchg_add:\n\t"
"ldq_l $0,0($16)\n\t"
"addq $0,$17,$1\n\t"
"stq_c $1,0($16)\n\t"
"ldl_l $0,0($16)\n\t"
"addl $0,$17,$1\n\t"
"stl_c $1,0($16)\n\t"
"beq $1,L0xchg_add\n\t"
"mb");
......
......@@ -312,9 +312,11 @@ void wine_pthread_init_current_teb( struct wine_pthread_thread_info *info )
# else
__asm__ __volatile__("mr 2, %0" : : "r" (info->teb_base));
# endif
#elif defined(HAVE__LWP_CREATE)
/* On non-i386 Solaris, we use the LWP private pointer */
_lwp_setprivate( info->teb_base );
#elif defined(__ALPHA__)
/* FIXME: On Alpha, the current TEB is not accessible to user-space */
/* __asm__ __volatile__();*/
#else
# error You must implement wine_pthread_init_current_teb for your platform
#endif
/* set pid and tid */
......@@ -344,6 +346,14 @@ void *wine_pthread_get_current_teb(void)
# else
__asm__( "mr %0,2" : "=r" (ret) );
# endif
#elif defined(__ALPHA__)
/* 0x00ab is the PAL opcode for rdteb */
__asm__( "lda $30,8($30)\n\t"
"stq $0,0($30)\n\t"
"call_pal 0x00ab\n\t"
"mov $0,%0\n\t"
"ldq $0,0($30)\n\t"
"lda $30,-8($30)" : "=r" (ret) );
#else
# error wine_pthread_get_current_teb not defined for this architecture
#endif /* __i386__ */
......
......@@ -8,6 +8,7 @@ IMPORTS = dbghelp advapi32 kernel32 ntdll
DELAYIMPORTS = user32
C_SRCS = \
be_alpha.c \
be_i386.c \
be_ppc.c \
break.c \
......
/*
* Debugger Alpha specific functions
*
* Copyright 2004 Vincent Bron
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "debugger.h"
#if defined(__ALPHA__)
static unsigned be_alpha_get_addr(HANDLE hThread, const CONTEXT* ctx,
enum be_cpu_addr bca, ADDRESS* addr)
{
dbg_printf("not done\n");
return FALSE;
}
static void be_alpha_single_step(CONTEXT* ctx, unsigned enable)
{
dbg_printf("not done\n");
}
static void be_alpha_print_context(HANDLE hThread, const CONTEXT* ctx)
{
dbg_printf("Context printing for Alpha not done yet\n");
}
static void be_alpha_print_segment_info(HANDLE hThread, const CONTEXT* ctx)
{
}
static struct dbg_internal_var be_alpha_ctx[] =
{
{0, NULL, 0, dbg_itype_none}
};
static const struct dbg_internal_var* be_alpha_init_registers(CONTEXT* ctx)
{
dbg_printf("not done\n");
return be_alpha_ctx;
}
static unsigned be_alpha_is_step_over_insn(void* insn)
{
dbg_printf("not done\n");
return FALSE;
}
static unsigned be_alpha_is_function_return(void* insn)
{
dbg_printf("not done\n");
return FALSE;
}
static unsigned be_alpha_is_break_insn(void* insn)
{
dbg_printf("not done\n");
return FALSE;
}
static unsigned be_alpha_is_func_call(void* insn, void** insn_callee)
{
return FALSE;
}
static void be_alpha_disasm_one_insn(ADDRESS* addr, int display)
{
dbg_printf("Disasm NIY\n");
}
static unsigned be_alpha_insert_Xpoint(HANDLE hProcess, CONTEXT* ctx,
enum be_xpoint_type type, void* addr,
unsigned long* val, unsigned size)
{
unsigned long xbp;
unsigned long sz;
switch (type)
{
case be_xpoint_break:
if (!size) return 0;
if (!ReadProcessMemory(hProcess, addr, val, 4, &sz) || sz != 4) return 0;
xbp = 0x7d821008; /* 7d 82 10 08 ... in big endian */
if (!WriteProcessMemory(hProcess, addr, &xbp, 4, &sz) || sz != 4) return 0;
break;
default:
dbg_printf("Unknown/unsupported bp type %c\n", type);
return 0;
}
return 1;
}
static unsigned be_alpha_remove_Xpoint(HANDLE hProcess, CONTEXT* ctx,
enum be_xpoint_type type, void* addr,
unsigned long val, unsigned size)
{
dbg_printf("not done\n");
return FALSE;
}
static unsigned be_alpha_is_watchpoint_set(const CONTEXT* ctx, unsigned idx)
{
dbg_printf("not done\n");
return FALSE;
}
static void be_alpha_clear_watchpoint(CONTEXT* ctx, unsigned idx)
{
dbg_printf("not done\n");
}
static int be_alpha_adjust_pc_for_break(CONTEXT* ctx, BOOL way)
{
dbg_printf("not done\n");
return 0;
}
static int be_alpha_fetch_integer(const struct dbg_lvalue* lvalue, unsigned size,
unsigned ext_sign, long long int* ret)
{
dbg_printf("not done\n");
return FALSE;
}
static int be_alpha_fetch_float(const struct dbg_lvalue* lvalue, unsigned size,
long double* ret)
{
dbg_printf("not done\n");
return FALSE;
}
struct backend_cpu be_alpha =
{
be_cpu_linearize,
be_cpu_build_addr,
be_alpha_get_addr,
be_alpha_single_step,
be_alpha_print_context,
be_alpha_print_segment_info,
be_alpha_init_registers,
be_alpha_is_step_over_insn,
be_alpha_is_function_return,
be_alpha_is_break_insn,
be_alpha_is_func_call,
be_alpha_disasm_one_insn,
be_alpha_insert_Xpoint,
be_alpha_remove_Xpoint,
be_alpha_is_watchpoint_set,
be_alpha_clear_watchpoint,
be_alpha_adjust_pc_for_break,
be_alpha_fetch_integer,
be_alpha_fetch_float,
};
#endif
......@@ -177,8 +177,7 @@ static size_t cpu_register_map[] = {
FIELD_OFFSET(CONTEXT, SegFs),
FIELD_OFFSET(CONTEXT, SegGs),
};
#else
# ifdef __powerpc__
#elif defined(__powerpc__)
static size_t cpu_register_map[] = {
FIELD_OFFSET(CONTEXT, Gpr0),
FIELD_OFFSET(CONTEXT, Gpr1),
......@@ -254,9 +253,80 @@ static size_t cpu_register_map[] = {
/* FIXME: MQ is missing? FIELD_OFFSET(CONTEXT, Mq), */
/* see gdb/nlm/ppc.c */
};
# else
# error "Define the registers map for your CPU"
# endif
#elif defined(__ALPHA__)
static size_t cpu_register_map[] = {
FIELD_OFFSET(CONTEXT, IntV0),
FIELD_OFFSET(CONTEXT, IntT0),
FIELD_OFFSET(CONTEXT, IntT1),
FIELD_OFFSET(CONTEXT, IntT2),
FIELD_OFFSET(CONTEXT, IntT3),
FIELD_OFFSET(CONTEXT, IntT4),
FIELD_OFFSET(CONTEXT, IntT5),
FIELD_OFFSET(CONTEXT, IntT6),
FIELD_OFFSET(CONTEXT, IntT7),
FIELD_OFFSET(CONTEXT, IntS0),
FIELD_OFFSET(CONTEXT, IntS1),
FIELD_OFFSET(CONTEXT, IntS2),
FIELD_OFFSET(CONTEXT, IntS3),
FIELD_OFFSET(CONTEXT, IntS4),
FIELD_OFFSET(CONTEXT, IntS5),
FIELD_OFFSET(CONTEXT, IntFp),
FIELD_OFFSET(CONTEXT, IntA0),
FIELD_OFFSET(CONTEXT, IntA1),
FIELD_OFFSET(CONTEXT, IntA2),
FIELD_OFFSET(CONTEXT, IntA3),
FIELD_OFFSET(CONTEXT, IntA4),
FIELD_OFFSET(CONTEXT, IntA5),
FIELD_OFFSET(CONTEXT, IntT8),
FIELD_OFFSET(CONTEXT, IntT9),
FIELD_OFFSET(CONTEXT, IntT10),
FIELD_OFFSET(CONTEXT, IntT11),
FIELD_OFFSET(CONTEXT, IntRa),
FIELD_OFFSET(CONTEXT, IntT12),
FIELD_OFFSET(CONTEXT, IntAt),
FIELD_OFFSET(CONTEXT, IntGp),
FIELD_OFFSET(CONTEXT, IntSp),
FIELD_OFFSET(CONTEXT, IntZero),
FIELD_OFFSET(CONTEXT, FltF0),
FIELD_OFFSET(CONTEXT, FltF1),
FIELD_OFFSET(CONTEXT, FltF2),
FIELD_OFFSET(CONTEXT, FltF3),
FIELD_OFFSET(CONTEXT, FltF4),
FIELD_OFFSET(CONTEXT, FltF5),
FIELD_OFFSET(CONTEXT, FltF6),
FIELD_OFFSET(CONTEXT, FltF7),
FIELD_OFFSET(CONTEXT, FltF8),
FIELD_OFFSET(CONTEXT, FltF9),
FIELD_OFFSET(CONTEXT, FltF10),
FIELD_OFFSET(CONTEXT, FltF11),
FIELD_OFFSET(CONTEXT, FltF12),
FIELD_OFFSET(CONTEXT, FltF13),
FIELD_OFFSET(CONTEXT, FltF14),
FIELD_OFFSET(CONTEXT, FltF15),
FIELD_OFFSET(CONTEXT, FltF16),
FIELD_OFFSET(CONTEXT, FltF17),
FIELD_OFFSET(CONTEXT, FltF18),
FIELD_OFFSET(CONTEXT, FltF19),
FIELD_OFFSET(CONTEXT, FltF20),
FIELD_OFFSET(CONTEXT, FltF21),
FIELD_OFFSET(CONTEXT, FltF22),
FIELD_OFFSET(CONTEXT, FltF23),
FIELD_OFFSET(CONTEXT, FltF24),
FIELD_OFFSET(CONTEXT, FltF25),
FIELD_OFFSET(CONTEXT, FltF26),
FIELD_OFFSET(CONTEXT, FltF27),
FIELD_OFFSET(CONTEXT, FltF28),
FIELD_OFFSET(CONTEXT, FltF29),
FIELD_OFFSET(CONTEXT, FltF30),
FIELD_OFFSET(CONTEXT, FltF31),
/* FIXME: Didn't look for the right order yet */
FIELD_OFFSET(CONTEXT, Fir),
FIELD_OFFSET(CONTEXT, Fpcr),
FIELD_OFFSET(CONTEXT, SoftFpcr),
};
#else
# error Define the registers map for your CPU
#endif
static const size_t cpu_num_regs = (sizeof(cpu_register_map) / sizeof(cpu_register_map[0]));
......
......@@ -1102,6 +1102,8 @@ struct backend_cpu* be_cpu;
extern struct backend_cpu be_i386;
#elif __powerpc__
extern struct backend_cpu be_ppc;
#elif __ALPHA__
extern struct backend_cpu be_alpha;
#else
# error CPU unknown
#endif
......@@ -1115,6 +1117,8 @@ int main(int argc, char** argv)
be_cpu = &be_i386;
#elif __powerpc__
be_cpu = &be_ppc;
#elif __ALPHA__
be_cpu = &be_alpha;
#else
# error CPU unknown
#endif
......
......@@ -749,6 +749,10 @@ static int output_immediate_imports( FILE *outfile )
fprintf(outfile, "\t\"\\tlwz %s, 0(%s)\\n\"\n", ppc_reg[9], ppc_reg[1]);
fprintf(outfile, "\t\"\\taddi %s, %s, 0x4\\n\"\n", ppc_reg[1], ppc_reg[1]);
fprintf(outfile, "\t\"\\tbctr\\n");
#elif defined(__ALPHA__)
fprintf( outfile, "\tlda $0,imports\\n\"\n" );
fprintf( outfile, "\t\"\\tlda $0,%d($0)\\n\"\n", pos);
fprintf( outfile, "\t\"\\tjmp $31,($0)\\n" );
#else
#error You need to define import thunks for your architecture!
#endif
......@@ -952,6 +956,9 @@ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
/* branch to ctr register. */
fprintf( outfile, " \"bctr\\n\"\n");
#elif defined(__ALPHA__)
fprintf( outfile, " \"\\tjsr $26,__wine_delay_load\\n\"\n" );
fprintf( outfile, " \"\\tjmp $31,($0)\\n\"\n" );
#else
#error You need to defined delayed import thunks for your architecture!
#endif
......@@ -997,6 +1004,10 @@ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
fprintf( outfile, " \"\\taddic %s, %s, 0x4\\n\"\n", ppc_reg[1], ppc_reg[1]);
fprintf( outfile, " \"\\tb " __ASM_NAME("__wine_delay_load_asm") "\\n\"\n");
#endif /* __APPLE__ */
#elif defined(__ALPHA__)
fprintf( outfile, " \"\\tlda $0,%d($31)\\n\"\n", j);
fprintf( outfile, " \"\\tldah $0,%d($0)\\n\"\n", idx);
fprintf( outfile, " \"\\tjmp $31,__wine_delay_load_asm\\n\"\n" );
#else
#error You need to defined delayed import thunks for your architecture!
#endif
......@@ -1064,6 +1075,10 @@ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
fprintf( outfile, "\t\"\\tlwz %s, 0(%s)\\n\"\n", ppc_reg[9], ppc_reg[1]);
fprintf( outfile, "\t\"\\taddi %s, %s, 0x4\\n\"\n", ppc_reg[1], ppc_reg[1]);
fprintf( outfile, "\t\"\\tbctr\\n\"");
#elif defined(__ALPHA__)
fprintf( outfile, "\t\"lda $0,delay_imports\\n\"\n" );
fprintf( outfile, "\t\"\\tlda $0,%d($0)\\n\"\n", pos);
fprintf( outfile, "\t\"\\tjmp $31,($0)\\n\"" );
#else
#error You need to define delayed import thunks for your architecture!
#endif
......
......@@ -468,6 +468,19 @@ void output_dll_init( FILE *outfile, const char *constructor, const char *destru
fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
}
# endif /* __APPLE__ */
#elif defined(__ALPHA__)
if (constructor)
{
fprintf( outfile, "asm(\"\\t.section\\t\\\".init\\\" ,\\\"ax\\\"\\n\"\n" );
fprintf( outfile, " \"\\tjsr $26," __ASM_NAME("%s") "\\n\"\n", constructor );
fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
}
if (destructor)
{
fprintf( outfile, "asm(\"\\t.section\\t\\\".fini\\\" ,\\\"ax\\\"\\n\"\n" );
fprintf( outfile, " \"\\tjsr $26," __ASM_NAME("%s") "\\n\"\n", destructor );
fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
}
#else
#error You need to define the DLL constructor for your architecture
#endif
......@@ -757,6 +770,8 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
fprintf( outfile, " { 0x%04x,\n", IMAGE_FILE_MACHINE_I386 ); /* Machine */
#elif defined(__powerpc__)
fprintf( outfile, " { 0x%04x,\n", IMAGE_FILE_MACHINE_POWERPC ); /* Machine */
#elif defined(__ALPHA__)
fprintf( outfile, " { 0x%04x,\n", IMAGE_FILE_MACHINE_ALPHA ); /* Machine */
#else
fprintf( outfile, " { 0x%04x,\n", IMAGE_FILE_MACHINE_UNKNOWN ); /* Machine */
#endif
......@@ -965,6 +980,12 @@ void BuildDebugFile( FILE *outfile, const char *srcdir, char **argv )
fprintf( outfile, " \"\\tbl " __ASM_NAME("__wine_dbg_%s_fini") "\\n\"\n", prefix );
fprintf( outfile, " \"\\t.text\\n\");\n" );
# endif
#elif defined(__ALPHA__)
fprintf( outfile, "asm(\"\\t.section\\t\\\".init\\\" ,\\\"ax\\\"\\n\"\n" );
fprintf( outfile, " \"\\tjsr $26," __ASM_NAME("__wine_dbg_%s_init") "\\n\"\n", prefix );
fprintf( outfile, " \"\\t.section\\t\\\".fini\\\" ,\\\"ax\\\"\\n\"\n" );
fprintf( outfile, " \"\\tjsr $26," __ASM_NAME("__wine_dbg_%s_fini") "\\n\"\n", prefix );
fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
#else
#error You need to define the DLL constructor for your architecture
#endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment