Re-introducing support for the sparc64 architecture

This commit is contained in:
Pierre Pronchery 2011-04-21 19:20:50 +00:00
parent 8ebf1b07af
commit fae68e5fd1
9 changed files with 433 additions and 234 deletions

View File

@ -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 \

View File

@ -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

View File

@ -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

View File

@ -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;
}

247
src/arch/sparc.h Normal file
View File

@ -0,0 +1,247 @@
/* $Id$ */
/* Copyright (c) 2011 Pierre Pronchery <khorben@defora.org> */
/* 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 <http://www.gnu.org/licenses/>. */
#include <stddef.h>
/* 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;
}

58
src/arch/sparc64.c Normal file
View File

@ -0,0 +1,58 @@
/* $Id$ */
/* Copyright (c) 2011 Pierre Pronchery <khorben@defora.org> */
/* 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 <http://www.gnu.org/licenses/>. */
#include <stddef.h>
#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
};

View File

@ -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)

View File

@ -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

79
test/sparc64.S Normal file
View File

@ -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