diff --git a/Makefile b/Makefile index 7107a45..1abfba6 100644 --- a/Makefile +++ b/Makefile @@ -55,6 +55,7 @@ dist: $(PACKAGE)-$(VERSION)/src/arch/i586.c \ $(PACKAGE)-$(VERSION)/src/arch/i686.c \ $(PACKAGE)-$(VERSION)/src/arch/sparc.c \ + $(PACKAGE)-$(VERSION)/src/arch/sparc64.c \ $(PACKAGE)-$(VERSION)/src/arch/Makefile \ $(PACKAGE)-$(VERSION)/src/arch/common.ins \ $(PACKAGE)-$(VERSION)/src/arch/i386.h \ @@ -65,6 +66,7 @@ dist: $(PACKAGE)-$(VERSION)/src/arch/i686.ins \ $(PACKAGE)-$(VERSION)/src/arch/i686.reg \ $(PACKAGE)-$(VERSION)/src/arch/null.ins \ + $(PACKAGE)-$(VERSION)/src/arch/sparc.h \ $(PACKAGE)-$(VERSION)/src/arch/sparc.ins \ $(PACKAGE)-$(VERSION)/src/arch/sparc.reg \ $(PACKAGE)-$(VERSION)/src/arch/project.conf \ @@ -81,6 +83,7 @@ dist: $(PACKAGE)-$(VERSION)/test/i586.S \ $(PACKAGE)-$(VERSION)/test/i686.S \ $(PACKAGE)-$(VERSION)/test/sparc.S \ + $(PACKAGE)-$(VERSION)/test/sparc64.S \ $(PACKAGE)-$(VERSION)/test/Makefile \ $(PACKAGE)-$(VERSION)/test/project.conf \ $(PACKAGE)-$(VERSION)/Makefile \ diff --git a/src/arch/Makefile b/src/arch/Makefile index df78e16..eb4484c 100644 --- a/src/arch/Makefile +++ b/src/arch/Makefile @@ -1,4 +1,4 @@ -TARGETS = i386.so i386_real.so i486.so i586.so i686.so sparc.so +TARGETS = i386.so i386_real.so i486.so i586.so i686.so sparc.so sparc64.so PREFIX = /usr/local DESTDIR = LIBDIR = $(PREFIX)/lib @@ -60,6 +60,13 @@ sparc_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) sparc.so: $(sparc_OBJS) $(LD) -o sparc.so $(sparc_OBJS) $(sparc_LDFLAGS) +sparc64_OBJS = sparc64.o +sparc64_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS) +sparc64_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) + +sparc64.so: $(sparc64_OBJS) + $(LD) -o sparc64.so $(sparc64_OBJS) $(sparc64_LDFLAGS) + i386.o: i386.c common.ins null.ins i386.h i386.ins i386.reg $(CC) $(i386_CFLAGS) -c i386.c @@ -75,11 +82,14 @@ i586.o: i586.c common.ins null.ins i386.h i386.ins i386.reg i486.ins i586.ins i686.o: i686.c common.ins null.ins i386.h i386.ins i386.reg i486.ins i686.ins i686.reg $(CC) $(i686_CFLAGS) -c i686.c -sparc.o: sparc.c common.ins null.ins sparc.ins sparc.reg +sparc.o: sparc.c common.ins null.ins sparc.h sparc.ins sparc.reg $(CC) $(sparc_CFLAGS) -c sparc.c +sparc64.o: sparc64.c common.ins null.ins sparc.h sparc.ins sparc.reg + $(CC) $(sparc64_CFLAGS) -c sparc64.c + clean: - $(RM) -- $(i386_OBJS) $(i386_real_OBJS) $(i486_OBJS) $(i586_OBJS) $(i686_OBJS) $(sparc_OBJS) + $(RM) -- $(i386_OBJS) $(i386_real_OBJS) $(i486_OBJS) $(i586_OBJS) $(i686_OBJS) $(sparc_OBJS) $(sparc64_OBJS) distclean: clean $(RM) -- $(TARGETS) @@ -97,6 +107,8 @@ install: $(TARGETS) $(INSTALL) -m 0644 -- i686.so $(DESTDIR)$(LIBDIR)/asm/arch/i686.so $(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch $(INSTALL) -m 0644 -- sparc.so $(DESTDIR)$(LIBDIR)/asm/arch/sparc.so + $(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch + $(INSTALL) -m 0644 -- sparc64.so $(DESTDIR)$(LIBDIR)/asm/arch/sparc64.so uninstall: $(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/i386.so @@ -105,5 +117,6 @@ uninstall: $(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/i586.so $(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/i686.so $(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/sparc.so + $(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/sparc64.so .PHONY: all clean distclean install uninstall diff --git a/src/arch/project.conf b/src/arch/project.conf index d4cc5f4..8e9531b 100644 --- a/src/arch/project.conf +++ b/src/arch/project.conf @@ -1,8 +1,8 @@ -targets=i386,i386_real,i486,i586,i686,sparc +targets=i386,i386_real,i486,i586,i686,sparc,sparc64 cppflags_force=-I ../../include cflags_force=-W `pkg-config --cflags libSystem` cflags=-Wall -fPIC -pedantic -dist=Makefile,common.ins,i386.h,i386.ins,i386.reg,i486.ins,i586.ins,i686.ins,i686.reg,null.ins,sparc.ins,sparc.reg +dist=Makefile,common.ins,i386.h,i386.ins,i386.reg,i486.ins,i586.ins,i686.ins,i686.reg,null.ins,sparc.h,sparc.ins,sparc.reg [i386] type=plugin @@ -50,4 +50,12 @@ sources=sparc.c install=$(LIBDIR)/asm/arch [sparc.c] -depends=common.ins,null.ins,sparc.ins,sparc.reg +depends=common.ins,null.ins,sparc.h,sparc.ins,sparc.reg + +[sparc64] +type=plugin +sources=sparc64.c +install=$(LIBDIR)/asm/arch + +[sparc64.c] +depends=common.ins,null.ins,sparc.h,sparc.ins,sparc.reg diff --git a/src/arch/sparc.c b/src/arch/sparc.c index 0eca75f..dea895b 100644 --- a/src/arch/sparc.c +++ b/src/arch/sparc.c @@ -39,10 +39,9 @@ static ArchInstruction _sparc_instructions[] = }; -/* prototypes */ +/* functions */ /* plug-in */ -static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction, - ArchInstructionCall * call); +#include "sparc.h" /* protected */ @@ -57,225 +56,3 @@ ArchPlugin arch_plugin = _sparc_write, NULL }; - - -/* private */ -/* functions */ -/* plug-in */ -/* sparc_write */ -static int _write_branch(ArchPlugin * plugin, ArchInstruction * instruction, - ArchInstructionCall * call, uint32_t * opcode); -static int _write_integer(ArchPlugin * plugin, ArchInstruction * instruction, - ArchInstructionCall * call, uint32_t * opcode); -static int _write_loadstore(ArchPlugin * plugin, ArchInstruction * instruction, - ArchInstructionCall * call, uint32_t * opcode); -static int _write_sethi(ArchPlugin * plugin, ArchInstruction * instruction, - ArchInstructionCall * call, uint32_t * opcode); - -static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction, - ArchInstructionCall * call) -{ - uint32_t opcode = instruction->opcode; - - if((opcode & 0xc0000000) == 0xc0000000) - { - if(_write_loadstore(plugin, instruction, call, &opcode) != 0) - return -1; - } - else if((opcode & 0xc1c00000) == 0x01000000) - { - if(_write_sethi(plugin, instruction, call, &opcode) != 0) - return -1; - } - else if((opcode & 0xc0000000) == 0x80000000) - { - if(_write_integer(plugin, instruction, call, &opcode) != 0) - return -1; - } - else if((opcode & 0xc1c00000) == 0x00800000) - { - if(_write_branch(plugin, instruction, call, &opcode) != 0) - return -1; - } - else - return -1; - opcode = _htob32(opcode); - if(fwrite(&opcode, sizeof(opcode), 1, plugin->helper->fp) != 1) - return -1; - return 0; -} - -static int _write_branch(ArchPlugin * plugin, ArchInstruction * instruction, - ArchInstructionCall * call, uint32_t * opcode) -{ - uint32_t disp; - - if(AO_GET_TYPE(instruction->op1) != AOT_IMMEDIATE) - return -1; - disp = call->operands[0].value.immediate.value; - if(call->operands[0].value.immediate.negative) - disp = -disp; - disp &= (0x003fffff); - *opcode |= disp; - return 0; -} - -static int _write_integer(ArchPlugin * plugin, ArchInstruction * instruction, - ArchInstructionCall * call, uint32_t * opcode) -{ - ArchPluginHelper * helper = plugin->helper; - uint32_t rd; - uint32_t rs1; - uint32_t rs2; - char const * name; - ArchRegister * ar; - - /* rs1 */ - if(AO_GET_TYPE(instruction->op1) != AOT_REGISTER) - return -1; - name = call->operands[0].value._register.name; - if((ar = helper->get_register_by_name_size(helper->arch, - name, 32)) == NULL) - return -1; - rs1 = (ar->id << 14); - /* rs2 */ - if(AO_GET_TYPE(instruction->op2) == AOT_REGISTER) - { - name = call->operands[1].value._register.name; - if((ar = helper->get_register_by_name_size(helper->arch, - name, 32)) == NULL) - return -1; - rs2 = ar->id; - } - else if(AO_GET_TYPE(instruction->op2) == AOT_IMMEDIATE) - { - rs2 = call->operands[1].value.immediate.value; - if(call->operands[1].value.immediate.negative) - rs2 = -rs2; - rs2 &= 0x00001fff; - rs2 |= (1 << 13); - } - else - return -1; - /* rd */ - if(AO_GET_TYPE(instruction->op3) != AOT_REGISTER) - return -1; - name = call->operands[2].value._register.name; - if((ar = helper->get_register_by_name_size(helper->arch, - name, 32)) == NULL) - return -1; - rd = (ar->id << 25); - *opcode |= (rd | rs1 | rs2); - return 0; -} - -static int _write_loadstore(ArchPlugin * plugin, ArchInstruction * instruction, - ArchInstructionCall * call, uint32_t * opcode) -{ - ArchPluginHelper * helper = plugin->helper; - uint32_t rd; - uint32_t rs1; - uint32_t rs2; - char const * name; - ArchRegister * ar; - - if(instruction->opcode & (1 << 21)) /* store instruction */ - { - /* rd */ - if(AO_GET_TYPE(instruction->op1) != AOT_REGISTER) - return -1; - name = call->operands[0].value._register.name; - if((ar = helper->get_register_by_name_size(helper->arch, - name, 32)) == NULL) - return -1; - rd = (ar->id << 25); - /* [rs1 + rs2] */ - if(AO_GET_TYPE(instruction->op2) == AOT_DREGISTER2) - { - name = call->operands[1].value.dregister2.name; - if((ar = helper->get_register_by_name_size(helper->arch, - name, 32)) == NULL) - return -1; - rs1 = (ar->id << 14); - name = call->operands[1].value.dregister2.name2; - if((ar = helper->get_register_by_name_size(helper->arch, - name, 32)) == NULL) - return -1; - rs2 = ar->id; - } - else if(AO_GET_TYPE(instruction->op2) == AOT_DREGISTER) - { - name = call->operands[1].value.dregister.name; - if((ar = helper->get_register_by_name_size(helper->arch, - name, 32)) == NULL) - return -1; - rs1 = (ar->id << 14); - rs2 = 0; /* FIXME implement */ - } - else - return -1; - } - else - { - /* [rs1 + rs2] */ - if(AO_GET_TYPE(instruction->op1) == AOT_DREGISTER2) - { - name = call->operands[0].value.dregister2.name; - if((ar = helper->get_register_by_name_size(helper->arch, - name, 32)) == NULL) - return -1; - rs1 = (ar->id << 14); - name = call->operands[0].value.dregister2.name2; - if((ar = helper->get_register_by_name_size(helper->arch, - name, 32)) == NULL) - return -1; - rs2 = ar->id; - } - else if(AO_GET_TYPE(instruction->op1) == AOT_DREGISTER) - { - name = call->operands[0].value.dregister.name; - if((ar = helper->get_register_by_name_size(helper->arch, - name, 32)) == NULL) - return -1; - rs1 = (ar->id << 14); - rs2 = 0; /* FIXME implement */ - } - else - return -1; - /* rd */ - if(AO_GET_TYPE(instruction->op2) != AOT_REGISTER) - return -1; - name = call->operands[1].value._register.name; - if((ar = helper->get_register_by_name_size(helper->arch, - name, 32)) == NULL) - return -1; - rd = (ar->id << 25); - } - *opcode |= (rd | rs1 | rs2); - return 0; -} - -static int _write_sethi(ArchPlugin * plugin, ArchInstruction * instruction, - ArchInstructionCall * call, uint32_t * opcode) -{ - ArchPluginHelper * helper = plugin->helper; - uint32_t rd; - uint32_t value; - char const * name; - ArchRegister * ar; - - /* value */ - if(AO_GET_TYPE(instruction->op1) != AOT_IMMEDIATE) - return -1; - value = (call->operands[0].value.immediate.value >> 10); - /* rd */ - if(AO_GET_TYPE(instruction->op2) != AOT_REGISTER) - return -1; - name = call->operands[1].value._register.name; - if((ar = helper->get_register_by_name_size(helper->arch, - name, 32)) == NULL) - return -1; - rd = (ar->id << 25); - *opcode |= (rd | value); - return 0; -} diff --git a/src/arch/sparc.h b/src/arch/sparc.h new file mode 100644 index 0000000..612283a --- /dev/null +++ b/src/arch/sparc.h @@ -0,0 +1,247 @@ +/* $Id$ */ +/* Copyright (c) 2011 Pierre Pronchery */ +/* This file is part of DeforaOS Devel as */ +/* This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + + + +#include + + +/* sparc */ +/* private */ +/* prototypes */ +/* plug-in */ +static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction, + ArchInstructionCall * call); + + +/* functions */ +/* plug-in */ +/* sparc_write */ +static int _write_branch(ArchInstruction * instruction, + ArchInstructionCall * call, uint32_t * opcode); +static int _write_integer(ArchPlugin * plugin, ArchInstruction * instruction, + ArchInstructionCall * call, uint32_t * opcode); +static int _write_loadstore(ArchPlugin * plugin, ArchInstruction * instruction, + ArchInstructionCall * call, uint32_t * opcode); +static int _write_sethi(ArchPlugin * plugin, ArchInstruction * instruction, + ArchInstructionCall * call, uint32_t * opcode); + +static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction, + ArchInstructionCall * call) +{ + uint32_t opcode = instruction->opcode; + + if((opcode & 0xc0000000) == 0xc0000000) + { + if(_write_loadstore(plugin, instruction, call, &opcode) != 0) + return -1; + } + else if((opcode & 0xc1c00000) == 0x01000000) + { + if(_write_sethi(plugin, instruction, call, &opcode) != 0) + return -1; + } + else if((opcode & 0xc0000000) == 0x80000000) + { + if(_write_integer(plugin, instruction, call, &opcode) != 0) + return -1; + } + else if((opcode & 0xc1c00000) == 0x00800000) + { + if(_write_branch(instruction, call, &opcode) != 0) + return -1; + } + else + return -1; + opcode = _htob32(opcode); + if(fwrite(&opcode, sizeof(opcode), 1, plugin->helper->fp) != 1) + return -1; + return 0; +} + +static int _write_branch(ArchInstruction * instruction, + ArchInstructionCall * call, uint32_t * opcode) +{ + uint32_t disp; + + if(AO_GET_TYPE(instruction->op1) != AOT_IMMEDIATE) + return -1; + disp = call->operands[0].value.immediate.value; + if(call->operands[0].value.immediate.negative) + disp = -disp; + disp &= (0x003fffff); + *opcode |= disp; + return 0; +} + +static int _write_integer(ArchPlugin * plugin, ArchInstruction * instruction, + ArchInstructionCall * call, uint32_t * opcode) +{ + ArchPluginHelper * helper = plugin->helper; + uint32_t rd; + uint32_t rs1; + uint32_t rs2; + char const * name; + ArchRegister * ar; + + /* rs1 */ + if(AO_GET_TYPE(instruction->op1) != AOT_REGISTER) + return -1; + name = call->operands[0].value._register.name; + if((ar = helper->get_register_by_name_size(helper->arch, + name, 32)) == NULL) + return -1; + rs1 = (ar->id << 14); + /* rs2 */ + if(AO_GET_TYPE(instruction->op2) == AOT_REGISTER) + { + name = call->operands[1].value._register.name; + if((ar = helper->get_register_by_name_size(helper->arch, + name, 32)) == NULL) + return -1; + rs2 = ar->id; + } + else if(AO_GET_TYPE(instruction->op2) == AOT_IMMEDIATE) + { + rs2 = call->operands[1].value.immediate.value; + if(call->operands[1].value.immediate.negative) + rs2 = -rs2; + rs2 &= 0x00001fff; + rs2 |= (1 << 13); + } + else + return -1; + /* rd */ + if(AO_GET_TYPE(instruction->op3) != AOT_REGISTER) + return -1; + name = call->operands[2].value._register.name; + if((ar = helper->get_register_by_name_size(helper->arch, + name, 32)) == NULL) + return -1; + rd = (ar->id << 25); + *opcode |= (rd | rs1 | rs2); + return 0; +} + +static int _write_loadstore(ArchPlugin * plugin, ArchInstruction * instruction, + ArchInstructionCall * call, uint32_t * opcode) +{ + ArchPluginHelper * helper = plugin->helper; + uint32_t rd; + uint32_t rs1; + uint32_t rs2; + char const * name; + ArchRegister * ar; + + if(instruction->opcode & (1 << 21)) /* store instruction */ + { + /* rd */ + if(AO_GET_TYPE(instruction->op1) != AOT_REGISTER) + return -1; + name = call->operands[0].value._register.name; + if((ar = helper->get_register_by_name_size(helper->arch, + name, 32)) == NULL) + return -1; + rd = (ar->id << 25); + /* [rs1 + rs2] */ + if(AO_GET_TYPE(instruction->op2) == AOT_DREGISTER2) + { + name = call->operands[1].value.dregister2.name; + if((ar = helper->get_register_by_name_size(helper->arch, + name, 32)) == NULL) + return -1; + rs1 = (ar->id << 14); + name = call->operands[1].value.dregister2.name2; + if((ar = helper->get_register_by_name_size(helper->arch, + name, 32)) == NULL) + return -1; + rs2 = ar->id; + } + else if(AO_GET_TYPE(instruction->op2) == AOT_DREGISTER) + { + name = call->operands[1].value.dregister.name; + if((ar = helper->get_register_by_name_size(helper->arch, + name, 32)) == NULL) + return -1; + rs1 = (ar->id << 14); + rs2 = 0; /* FIXME implement */ + } + else + return -1; + } + else + { + /* [rs1 + rs2] */ + if(AO_GET_TYPE(instruction->op1) == AOT_DREGISTER2) + { + name = call->operands[0].value.dregister2.name; + if((ar = helper->get_register_by_name_size(helper->arch, + name, 32)) == NULL) + return -1; + rs1 = (ar->id << 14); + name = call->operands[0].value.dregister2.name2; + if((ar = helper->get_register_by_name_size(helper->arch, + name, 32)) == NULL) + return -1; + rs2 = ar->id; + } + else if(AO_GET_TYPE(instruction->op1) == AOT_DREGISTER) + { + name = call->operands[0].value.dregister.name; + if((ar = helper->get_register_by_name_size(helper->arch, + name, 32)) == NULL) + return -1; + rs1 = (ar->id << 14); + rs2 = 0; /* FIXME implement */ + } + else + return -1; + /* rd */ + if(AO_GET_TYPE(instruction->op2) != AOT_REGISTER) + return -1; + name = call->operands[1].value._register.name; + if((ar = helper->get_register_by_name_size(helper->arch, + name, 32)) == NULL) + return -1; + rd = (ar->id << 25); + } + *opcode |= (rd | rs1 | rs2); + return 0; +} + +static int _write_sethi(ArchPlugin * plugin, ArchInstruction * instruction, + ArchInstructionCall * call, uint32_t * opcode) +{ + ArchPluginHelper * helper = plugin->helper; + uint32_t rd; + uint32_t value; + char const * name; + ArchRegister * ar; + + /* value */ + if(AO_GET_TYPE(instruction->op1) != AOT_IMMEDIATE) + return -1; + value = (call->operands[0].value.immediate.value >> 10); + /* rd */ + if(AO_GET_TYPE(instruction->op2) != AOT_REGISTER) + return -1; + name = call->operands[1].value._register.name; + if((ar = helper->get_register_by_name_size(helper->arch, + name, 32)) == NULL) + return -1; + rd = (ar->id << 25); + *opcode |= (rd | value); + return 0; +} diff --git a/src/arch/sparc64.c b/src/arch/sparc64.c new file mode 100644 index 0000000..9582730 --- /dev/null +++ b/src/arch/sparc64.c @@ -0,0 +1,58 @@ +/* $Id$ */ +/* Copyright (c) 2011 Pierre Pronchery */ +/* This file is part of DeforaOS Devel as */ +/* This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + + + +#include +#include "Asm.h" + + +/* sparc64 */ +/* private */ +/* variables */ +static ArchDescription _sparc64_description = +{ "elf", ARCH_ENDIAN_BIG, 32, 32 }; + +#define REG(name, size, id) { "" # name, size, id }, +static ArchRegister _sparc64_registers[] = +{ +#include "sparc.reg" + { NULL, 0, 0 } +}; + +static ArchInstruction _sparc64_instructions[] = +{ +#include "sparc.ins" +#include "common.ins" +#include "null.ins" +}; + + +/* functions */ +#include "sparc.h" + + +/* protected */ +/* variables */ +ArchPlugin arch_plugin = +{ + NULL, + "sparc64", + &_sparc64_description, + _sparc64_registers, + _sparc64_instructions, + _sparc_write, + NULL +}; diff --git a/test/Makefile b/test/Makefile index b8aa835..6bfcf05 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,4 +1,4 @@ -TARGETS = i386.o i386_real.o i486.o i586.o i686.o sparc.o +TARGETS = i386.o i386_real.o i486.o i586.o i686.o sparc.o sparc64.o PREFIX = /usr/local DESTDIR = BINDIR = $(PREFIX)/bin @@ -30,6 +30,9 @@ i686.o_ASFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(ASFLAGS) -a i686 -f flat sparc.o_OBJS = sparc.o sparc.o_ASFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(ASFLAGS) -a sparc -f flat +sparc64.o_OBJS = sparc64.o +sparc64.o_ASFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(ASFLAGS) -a sparc64 -f flat + i386.o: i386.S ../src/asm $(AS) $(i386.o_ASFLAGS) -o i386.o i386.S @@ -48,8 +51,11 @@ i686.o: i686.S ../src/asm sparc.o: sparc.S ../src/asm $(AS) $(sparc.o_ASFLAGS) -o sparc.o sparc.S +sparc64.o: sparc64.S ../src/asm + $(AS) $(sparc64.o_ASFLAGS) -o sparc64.o sparc64.S + clean: - $(RM) -- $(i386.o_OBJS) $(i386_real.o_OBJS) $(i486.o_OBJS) $(i586.o_OBJS) $(i686.o_OBJS) $(sparc.o_OBJS) + $(RM) -- $(i386.o_OBJS) $(i386_real.o_OBJS) $(i486.o_OBJS) $(i586.o_OBJS) $(i686.o_OBJS) $(sparc.o_OBJS) $(sparc64.o_OBJS) distclean: clean $(RM) -- $(TARGETS) diff --git a/test/project.conf b/test/project.conf index 820fc80..a9e0091 100644 --- a/test/project.conf +++ b/test/project.conf @@ -1,4 +1,4 @@ -targets=i386.o,i386_real.o,i486.o,i586.o,i686.o,sparc.o +targets=i386.o,i386_real.o,i486.o,i586.o,i686.o,sparc.o,sparc64.o as=../src/asm dist=Makefile @@ -49,3 +49,11 @@ sources=sparc.S [sparc.S] asflags=-a sparc -f flat depends=../src/asm + +[sparc64.o] +type=object +sources=sparc64.S + +[sparc64.S] +asflags=-a sparc64 -f flat +depends=../src/asm diff --git a/test/sparc64.S b/test/sparc64.S new file mode 100644 index 0000000..e8cfec6 --- /dev/null +++ b/test/sparc64.S @@ -0,0 +1,79 @@ +.text + ldd [%r4 + %r7], %r11 /* 0xd6190007 */ + ldub [%r23], %r19 /* 0xe60dc000 */ + sub %r16, %r26, %r27 /* 0xb624001a */ + smulcc %r29, -$23, %r19 /* 0xa6df7fe9 */ + + add %r16, %r26, %r27 + add %r29, -$23, %r19 + addcc %r16, %r26, %r27 + addcc %r29, -$23, %r19 + and %r16, %r26, %r27 + and %r29, -$23, %r19 + andcc %r16, %r26, %r27 + andcc %r29, -$23, %r19 + andn %r16, %r26, %r27 + andn %r29, -$23, %r19 + andncc %r16, %r26, %r27 + andncc %r29, -$23, %r19 + ba $0x3 + be $0x3 + bg $0x3 + bge $0x3 + bl $0x3 + ble $0x3 + bne $0x3 /* 0x12800003 */ + bz $0x3 + ld [%r4 + %r7], %r11 + ld [%r23], %r19 + ldd [%r4 + %r7], %r11 + ldd [%r23], %r19 + ldsb [%r4 + %r7], %r11 + ldsb [%r23], %r19 + ldsh [%r4 + %r7], %r11 + ldsh [%r23], %r19 + ldub [%r4 + %r7], %r11 + ldub [%r23], %r19 + lduh [%r4 + %r7], %r11 + lduh [%r23], %r19 + or %r16, %r26, %r27 + or %r29, -$23, %r19 + orcc %r16, %r26, %r27 + orcc %r29, -$23, %r19 + orn %r16, %r26, %r27 + orn %r29, -$23, %r19 + orncc %r16, %r26, %r27 + orncc %r29, -$23, %r19 + sdiv %r16, %r26, %r27 + sdiv %r29, -$23, %r19 + sdivcc %r16, %r26, %r27 + sdivcc %r29, -$23, %r19 + sethi $0x87654321, %r2 /* 0x0521d950 */ + smul %r16, %r26, %r27 + smul %r29, -$23, %r19 + smulcc %r16, %r26, %r27 + smulcc %r29, -$23, %r19 + st %r11, [%r4 + %r7] + st %r19, [%r23] + stb %r11, [%r4 + %r7] + stb %r19, [%r23] + std %r11, [%r4 + %r7] + std %r19, [%r23] + sth %r11, [%r4 + %r7] + sth %r19, [%r23] + udiv %r16, %r26, %r27 + udiv %r29, -$23, %r19 + udivcc %r16, %r26, %r27 + udivcc %r29, -$23, %r19 + umul %r16, %r26, %r27 + umul %r29, -$23, %r19 + umulcc %r16, %r26, %r27 + umulcc %r29, -$23, %r19 + xnor %r16, %r26, %r27 + xnor %r29, -$23, %r19 + xnorcc %r16, %r26, %r27 + xnorcc %r29, -$23, %r19 + xor %r16, %r26, %r27 + xor %r29, -$23, %r19 + xorcc %r16, %r26, %r27 + xorcc %r29, -$23, %r19