diff --git a/Makefile b/Makefile index 9ce264e..4e42b06 100644 --- a/Makefile +++ b/Makefile @@ -50,11 +50,14 @@ dist: $(PACKAGE)-$(VERSION)/src/token.h \ $(PACKAGE)-$(VERSION)/src/project.conf \ $(PACKAGE)-$(VERSION)/src/arch/i386.c \ + $(PACKAGE)-$(VERSION)/src/arch/i486.c \ $(PACKAGE)-$(VERSION)/src/arch/sparc.c \ $(PACKAGE)-$(VERSION)/src/arch/Makefile \ $(PACKAGE)-$(VERSION)/src/arch/common.ins \ + $(PACKAGE)-$(VERSION)/src/arch/i386.h \ $(PACKAGE)-$(VERSION)/src/arch/i386.ins \ $(PACKAGE)-$(VERSION)/src/arch/i386.reg \ + $(PACKAGE)-$(VERSION)/src/arch/i486.ins \ $(PACKAGE)-$(VERSION)/src/arch/null.ins \ $(PACKAGE)-$(VERSION)/src/arch/sparc.ins \ $(PACKAGE)-$(VERSION)/src/arch/sparc.reg \ @@ -67,6 +70,7 @@ dist: $(PACKAGE)-$(VERSION)/src/format/Makefile \ $(PACKAGE)-$(VERSION)/src/format/project.conf \ $(PACKAGE)-$(VERSION)/test/i386.S \ + $(PACKAGE)-$(VERSION)/test/i486.S \ $(PACKAGE)-$(VERSION)/test/sparc.S \ $(PACKAGE)-$(VERSION)/test/Makefile \ $(PACKAGE)-$(VERSION)/test/project.conf \ diff --git a/src/arch/Makefile b/src/arch/Makefile index 06d74ee..407ec5f 100644 --- a/src/arch/Makefile +++ b/src/arch/Makefile @@ -1,4 +1,4 @@ -TARGETS = i386.so sparc.so +TARGETS = i386.so i486.so sparc.so PREFIX = /usr/local DESTDIR = LIBDIR = $(PREFIX)/lib @@ -25,6 +25,13 @@ i386_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) i386.so: $(i386_OBJS) $(LD) -o i386.so $(i386_OBJS) $(i386_LDFLAGS) +i486_OBJS = i486.o +i486_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS) +i486_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) + +i486.so: $(i486_OBJS) + $(LD) -o i486.so $(i486_OBJS) $(i486_LDFLAGS) + sparc_OBJS = sparc.o sparc_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS) sparc_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) @@ -32,14 +39,17 @@ sparc_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) sparc.so: $(sparc_OBJS) $(LD) -o sparc.so $(sparc_OBJS) $(sparc_LDFLAGS) -i386.o: i386.c common.ins null.ins i386.ins i386.reg +i386.o: i386.c common.ins null.ins i386.h i386.ins i386.reg $(CC) $(i386_CFLAGS) -c i386.c +i486.o: i486.c common.ins null.ins i386.h i386.ins i386.reg i486.ins + $(CC) $(i486_CFLAGS) -c i486.c + sparc.o: sparc.c common.ins null.ins sparc.ins sparc.reg $(CC) $(sparc_CFLAGS) -c sparc.c clean: - $(RM) -- $(i386_OBJS) $(sparc_OBJS) + $(RM) -- $(i386_OBJS) $(i486_OBJS) $(sparc_OBJS) distclean: clean $(RM) -- $(TARGETS) @@ -48,10 +58,13 @@ install: $(TARGETS) $(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch $(INSTALL) -m 0644 -- i386.so $(DESTDIR)$(LIBDIR)/asm/arch/i386.so $(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch + $(INSTALL) -m 0644 -- i486.so $(DESTDIR)$(LIBDIR)/asm/arch/i486.so + $(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch $(INSTALL) -m 0644 -- sparc.so $(DESTDIR)$(LIBDIR)/asm/arch/sparc.so uninstall: $(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/i386.so + $(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/i486.so $(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/sparc.so .PHONY: all clean distclean install uninstall diff --git a/src/arch/i386.c b/src/arch/i386.c index 6f5321a..f7469b6 100644 --- a/src/arch/i386.c +++ b/src/arch/i386.c @@ -59,9 +59,8 @@ static ArchInstruction _i386_instructions[] = }; -/* prototypes */ -static int _i386_write(ArchPlugin * plugin, ArchInstruction * instruction, - ArchInstructionCall * call); +/* functions */ +#include "i386.h" /* public */ @@ -77,232 +76,3 @@ ArchPlugin arch_plugin = _i386_write, NULL }; - - - -/* functions */ -static int _write_dregister(ArchPlugin * plugin, uint32_t * i, - ArchOperandDefinition * definitions, ArchOperand * operands); -static int _write_immediate(ArchPlugin * plugin, - ArchOperandDefinition definition, ArchOperand * operand); -static int _write_immediate8(ArchPlugin * plugin, uint8_t value); -static int _write_immediate16(ArchPlugin * plugin, uint16_t value); -static int _write_immediate32(ArchPlugin * plugin, uint32_t value); -static int _write_opcode(ArchPlugin * plugin, ArchInstruction * instruction); -static int _write_operand(ArchPlugin * plugin, uint32_t * i, - ArchOperandDefinition * definitions, ArchOperand * operands); -static int _write_register(ArchPlugin * plugin, uint32_t * i, - ArchOperandDefinition * definitions, ArchOperand * operands); - -static int _i386_write(ArchPlugin * plugin, ArchInstruction * instruction, - ArchInstructionCall * call) -{ - uint32_t i; - ArchOperandDefinition definitions[3]; - -#ifdef DEBUG - fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, instruction->name); -#endif - if(_write_opcode(plugin, instruction) != 0) - return -1; - definitions[0] = instruction->op1; - definitions[1] = instruction->op2; - definitions[2] = instruction->op3; - for(i = 0; i < call->operands_cnt; i++) - if(_write_operand(plugin, &i, definitions, call->operands) != 0) - return -1; - return 0; -} - -static int _write_dregister(ArchPlugin * plugin, uint32_t * i, - ArchOperandDefinition * definitions, ArchOperand * operands) -{ - ArchPluginHelper * helper = plugin->helper; - ArchOperandDefinition definition = definitions[*i]; - ArchOperand * operand = &operands[*i]; - char const * name = operand->value._register.name; - size_t size = AO_GET_SIZE(definition); - ArchRegister * ar; - ArchOperandDefinition idefinition; - ArchOperand ioperand; - - if((ar = helper->get_register_by_name_size(helper->arch, name, size)) - == NULL) - return -1; - /* write register */ - idefinition = AO_IMMEDIATE(0, 0, 8); - memset(&ioperand, 0, sizeof(ioperand)); - ioperand.type = AOT_IMMEDIATE; - ioperand.value.immediate.value = ar->id; - if(AO_GET_FLAGS(definition) & AOF_I386_MODRM - && AO_GET_VALUE(definition) == 8) /* mod r/m, /r */ - { - (*i)++; /* skip next operand */ - /* FIXME it could as well be an inverted /r */ - name = operands[*i].value._register.name; - size = AO_GET_SIZE(definitions[*i]); - if((ar = helper->get_register_by_name_size(helper->arch, name, - size)) == NULL) - return -1; - ioperand.value.immediate.value |= (ar->id << 3); - } - else if(AO_GET_FLAGS(definition) & AOF_I386_MODRM) /* mod r/m, /[0-7] */ - ioperand.value.immediate.value |= (AO_GET_VALUE(definition) - << 3); - if(operand->value.dregister.offset == 0) - /* there is no offset */ - return _write_immediate(plugin, idefinition, &ioperand); - /* declare offset */ - switch(AO_GET_OFFSET(definition) >> 3) - { - case sizeof(uint8_t): - ioperand.value.immediate.value |= 0x40; - break; - case W >> 3: - ioperand.value.immediate.value |= 0x80; - break; - default: - return -1; /* FIXME report error */ - } - if(_write_immediate(plugin, idefinition, &ioperand) != 0) - return -1; - /* write offset */ - idefinition = AO_IMMEDIATE(0, 0, AO_GET_OFFSET(definition)); - ioperand.value.immediate.value = operand->value.dregister.offset; - return _write_immediate(plugin, idefinition, &ioperand); -} - -static int _write_immediate(ArchPlugin * plugin, - ArchOperandDefinition definition, ArchOperand * operand) -{ - uint64_t value = operand->value.immediate.value; - - if((AO_GET_FLAGS(definition) & AOF_SIGNED) - && operand->value.immediate.negative != 0) - value = -value; - switch(AO_GET_SIZE(definition) >> 3) - { - case 0: - return 0; - case sizeof(uint8_t): - return _write_immediate8(plugin, value); - case sizeof(uint16_t): - return _write_immediate16(plugin, value); - case sizeof(uint32_t): - return _write_immediate32(plugin, value); - default: - return -1; - } -} - -static int _write_immediate8(ArchPlugin * plugin, uint8_t value) -{ - if(fwrite(&value, sizeof(value), 1, plugin->helper->fp) != 1) - return -1; - return 0; -} - -static int _write_immediate16(ArchPlugin * plugin, uint16_t value) -{ - value = _htol16(value); - if(fwrite(&value, sizeof(value), 1, plugin->helper->fp) != 1) - return -1; - return 0; -} - -static int _write_immediate32(ArchPlugin * plugin, uint32_t value) -{ - value = _htol32(value); - if(fwrite(&value, sizeof(value), 1, plugin->helper->fp) != 1) - return -1; - return 0; -} - -static int _write_opcode(ArchPlugin * plugin, ArchInstruction * instruction) -{ - ArchOperand operand; - -#ifdef DEBUG - fprintf(stderr, "DEBUG: %s() size=%u opcode=0x%x\n", __func__, - AO_GET_SIZE(instruction->flags), instruction->opcode); -#endif - memset(&operand, 0, sizeof(operand)); - operand.type = AOT_IMMEDIATE; - switch(AO_GET_SIZE(instruction->flags) >> 3) - { - case sizeof(uint8_t): - operand.value.immediate.value = instruction->opcode; - break; - case sizeof(uint16_t): - operand.value.immediate.value = _htob16( - instruction->opcode); - break; - case sizeof(uint32_t): - operand.value.immediate.value = _htob32( - instruction->opcode); - break; - default: - return -1; /* FIXME report error */ - } - return _write_immediate(plugin, instruction->flags, &operand); -} - -static int _write_operand(ArchPlugin * plugin, uint32_t * i, - ArchOperandDefinition * definitions, ArchOperand * operands) -{ - switch(operands[*i].type) - { - case AOT_DREGISTER: - return _write_dregister(plugin, i, definitions, - operands); - case AOT_IMMEDIATE: - return _write_immediate(plugin, definitions[*i], - &operands[*i]); - case AOT_REGISTER: - return _write_register(plugin, i, definitions, - operands); - } - return 0; -} - -static int _write_register(ArchPlugin * plugin, uint32_t * i, - ArchOperandDefinition * definitions, ArchOperand * operands) -{ - ArchPluginHelper * helper = plugin->helper; - ArchOperandDefinition definition = definitions[*i]; - ArchOperand * operand = &operands[*i]; - char const * name = operand->value._register.name; - size_t size = AO_GET_SIZE(definition); - ArchRegister * ar; - ArchOperandDefinition idefinition; - ArchOperand ioperand; - - if(AO_GET_FLAGS(definition) & AOF_IMPLICIT) - return 0; - if((ar = helper->get_register_by_name_size(helper->arch, name, size)) - == NULL) - return -1; - /* write register */ - idefinition = AO_IMMEDIATE(0, 0, 8); - memset(&ioperand, 0, sizeof(ioperand)); - ioperand.type = AOT_IMMEDIATE; - ioperand.value.immediate.value = ar->id; - if(AO_GET_FLAGS(definition) & AOF_I386_MODRM - && AO_GET_VALUE(definition) == 8) /* mod r/m, /r */ - { - (*i)++; /* skip next operand */ - /* FIXME it could as well be an inverted /r */ - name = operands[*i].value._register.name; - size = AO_GET_SIZE(definitions[*i]); - if((ar = helper->get_register_by_name_size(helper->arch, name, - size)) == NULL) - return -1; - ioperand.value.immediate.value |= 0xc0 | (ar->id << 3); - } - else if(AO_GET_FLAGS(definition) & AOF_I386_MODRM) /* mod r/m, /[0-7] */ - ioperand.value.immediate.value = 0xc0 | ar->id - | (AO_GET_VALUE(definition) << 3); - else - ioperand.value.immediate.value = ar->id; - return _write_immediate(plugin, idefinition, &ioperand); -} diff --git a/src/arch/i386.h b/src/arch/i386.h new file mode 100644 index 0000000..cfbf6f7 --- /dev/null +++ b/src/arch/i386.h @@ -0,0 +1,250 @@ +/* $Id$ */ +/* Copyright (c) 2011 Pierre Pronchery */ +/* This file is part of DeforaOS Devel asm */ +/* 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 . */ + + + +/* i386 */ +/* private */ +/* prototypes */ +static int _i386_write(ArchPlugin * plugin, ArchInstruction * instruction, + ArchInstructionCall * call); + + +/* functions */ +static int _write_dregister(ArchPlugin * plugin, uint32_t * i, + ArchOperandDefinition * definitions, ArchOperand * operands); +static int _write_immediate(ArchPlugin * plugin, + ArchOperandDefinition definition, ArchOperand * operand); +static int _write_immediate8(ArchPlugin * plugin, uint8_t value); +static int _write_immediate16(ArchPlugin * plugin, uint16_t value); +static int _write_immediate32(ArchPlugin * plugin, uint32_t value); +static int _write_opcode(ArchPlugin * plugin, ArchInstruction * instruction); +static int _write_operand(ArchPlugin * plugin, uint32_t * i, + ArchOperandDefinition * definitions, ArchOperand * operands); +static int _write_register(ArchPlugin * plugin, uint32_t * i, + ArchOperandDefinition * definitions, ArchOperand * operands); + +static int _i386_write(ArchPlugin * plugin, ArchInstruction * instruction, + ArchInstructionCall * call) +{ + uint32_t i; + ArchOperandDefinition definitions[3]; + +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, instruction->name); +#endif + if(_write_opcode(plugin, instruction) != 0) + return -1; + definitions[0] = instruction->op1; + definitions[1] = instruction->op2; + definitions[2] = instruction->op3; + for(i = 0; i < call->operands_cnt; i++) + if(_write_operand(plugin, &i, definitions, call->operands) != 0) + return -1; + return 0; +} + +static int _write_dregister(ArchPlugin * plugin, uint32_t * i, + ArchOperandDefinition * definitions, ArchOperand * operands) +{ + ArchPluginHelper * helper = plugin->helper; + ArchOperandDefinition definition = definitions[*i]; + ArchOperand * operand = &operands[*i]; + char const * name = operand->value._register.name; + size_t size = AO_GET_SIZE(definition); + ArchRegister * ar; + ArchOperandDefinition idefinition; + ArchOperand ioperand; + + if((ar = helper->get_register_by_name_size(helper->arch, name, size)) + == NULL) + return -1; + /* write register */ + idefinition = AO_IMMEDIATE(0, 0, 8); + memset(&ioperand, 0, sizeof(ioperand)); + ioperand.type = AOT_IMMEDIATE; + ioperand.value.immediate.value = ar->id; + if(AO_GET_FLAGS(definition) & AOF_I386_MODRM + && AO_GET_VALUE(definition) == 8) /* mod r/m, /r */ + { + (*i)++; /* skip next operand */ + /* FIXME it could as well be an inverted /r */ + name = operands[*i].value._register.name; + size = AO_GET_SIZE(definitions[*i]); + if((ar = helper->get_register_by_name_size(helper->arch, name, + size)) == NULL) + return -1; + ioperand.value.immediate.value |= (ar->id << 3); + } + else if(AO_GET_FLAGS(definition) & AOF_I386_MODRM) /* mod r/m, /[0-7] */ + ioperand.value.immediate.value |= (AO_GET_VALUE(definition) + << 3); + if(operand->value.dregister.offset == 0) + /* there is no offset */ + return _write_immediate(plugin, idefinition, &ioperand); + /* declare offset */ + switch(AO_GET_OFFSET(definition) >> 3) + { + case sizeof(uint8_t): + ioperand.value.immediate.value |= 0x40; + break; + case W >> 3: + ioperand.value.immediate.value |= 0x80; + break; + default: + return -1; /* FIXME report error */ + } + if(_write_immediate(plugin, idefinition, &ioperand) != 0) + return -1; + /* write offset */ + idefinition = AO_IMMEDIATE(0, 0, AO_GET_OFFSET(definition)); + ioperand.value.immediate.value = operand->value.dregister.offset; + return _write_immediate(plugin, idefinition, &ioperand); +} + +static int _write_immediate(ArchPlugin * plugin, + ArchOperandDefinition definition, ArchOperand * operand) +{ + uint64_t value = operand->value.immediate.value; + + if((AO_GET_FLAGS(definition) & AOF_SIGNED) + && operand->value.immediate.negative != 0) + value = -value; + switch(AO_GET_SIZE(definition) >> 3) + { + case 0: + return 0; + case sizeof(uint8_t): + return _write_immediate8(plugin, value); + case sizeof(uint16_t): + return _write_immediate16(plugin, value); + case sizeof(uint32_t): + return _write_immediate32(plugin, value); + default: + return -1; + } +} + +static int _write_immediate8(ArchPlugin * plugin, uint8_t value) +{ + if(fwrite(&value, sizeof(value), 1, plugin->helper->fp) != 1) + return -1; + return 0; +} + +static int _write_immediate16(ArchPlugin * plugin, uint16_t value) +{ + value = _htol16(value); + if(fwrite(&value, sizeof(value), 1, plugin->helper->fp) != 1) + return -1; + return 0; +} + +static int _write_immediate32(ArchPlugin * plugin, uint32_t value) +{ + value = _htol32(value); + if(fwrite(&value, sizeof(value), 1, plugin->helper->fp) != 1) + return -1; + return 0; +} + +static int _write_opcode(ArchPlugin * plugin, ArchInstruction * instruction) +{ + ArchOperand operand; + +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s() size=%u opcode=0x%x\n", __func__, + AO_GET_SIZE(instruction->flags), instruction->opcode); +#endif + memset(&operand, 0, sizeof(operand)); + operand.type = AOT_IMMEDIATE; + switch(AO_GET_SIZE(instruction->flags) >> 3) + { + case sizeof(uint8_t): + operand.value.immediate.value = instruction->opcode; + break; + case sizeof(uint16_t): + operand.value.immediate.value = _htob16( + instruction->opcode); + break; + case sizeof(uint32_t): + operand.value.immediate.value = _htob32( + instruction->opcode); + break; + default: + return -1; /* FIXME report error */ + } + return _write_immediate(plugin, instruction->flags, &operand); +} + +static int _write_operand(ArchPlugin * plugin, uint32_t * i, + ArchOperandDefinition * definitions, ArchOperand * operands) +{ + switch(operands[*i].type) + { + case AOT_DREGISTER: + return _write_dregister(plugin, i, definitions, + operands); + case AOT_IMMEDIATE: + return _write_immediate(plugin, definitions[*i], + &operands[*i]); + case AOT_REGISTER: + return _write_register(plugin, i, definitions, + operands); + } + return 0; +} + +static int _write_register(ArchPlugin * plugin, uint32_t * i, + ArchOperandDefinition * definitions, ArchOperand * operands) +{ + ArchPluginHelper * helper = plugin->helper; + ArchOperandDefinition definition = definitions[*i]; + ArchOperand * operand = &operands[*i]; + char const * name = operand->value._register.name; + size_t size = AO_GET_SIZE(definition); + ArchRegister * ar; + ArchOperandDefinition idefinition; + ArchOperand ioperand; + + if(AO_GET_FLAGS(definition) & AOF_IMPLICIT) + return 0; + if((ar = helper->get_register_by_name_size(helper->arch, name, size)) + == NULL) + return -1; + /* write register */ + idefinition = AO_IMMEDIATE(0, 0, 8); + memset(&ioperand, 0, sizeof(ioperand)); + ioperand.type = AOT_IMMEDIATE; + ioperand.value.immediate.value = ar->id; + if(AO_GET_FLAGS(definition) & AOF_I386_MODRM + && AO_GET_VALUE(definition) == 8) /* mod r/m, /r */ + { + (*i)++; /* skip next operand */ + /* FIXME it could as well be an inverted /r */ + name = operands[*i].value._register.name; + size = AO_GET_SIZE(definitions[*i]); + if((ar = helper->get_register_by_name_size(helper->arch, name, + size)) == NULL) + return -1; + ioperand.value.immediate.value |= 0xc0 | (ar->id << 3); + } + else if(AO_GET_FLAGS(definition) & AOF_I386_MODRM) /* mod r/m, /[0-7] */ + ioperand.value.immediate.value = 0xc0 | ar->id + | (AO_GET_VALUE(definition) << 3); + else + ioperand.value.immediate.value = ar->id; + return _write_immediate(plugin, idefinition, &ioperand); +} diff --git a/src/arch/i386.ins b/src/arch/i386.ins index 1257d49..358e1b5 100644 --- a/src/arch/i386.ins +++ b/src/arch/i386.ins @@ -19,6 +19,14 @@ #define OP_RW AO_REGISTER(0, W, 0) #define OP_al AO_REGISTER(AOF_IMPLICIT, REG_al_size, REG_al_id) #define OP_AX AO_REGISTER(AOF_IMPLICIT, W, REG_AX_id) +#define OP_eax AO_REGISTER(AOF_IMPLICIT, 32, REG_eax_id) +#define OP_ecx AO_REGISTER(AOF_IMPLICIT, 32, REG_ecx_id) +#define OP_edx AO_REGISTER(AOF_IMPLICIT, 32, REG_edx_id) +#define OP_ebx AO_REGISTER(AOF_IMPLICIT, 32, REG_ebx_id) +#define OP_esp AO_REGISTER(AOF_IMPLICIT, 32, REG_esp_id) +#define OP_ebp AO_REGISTER(AOF_IMPLICIT, 32, REG_ebp_id) +#define OP_esi AO_REGISTER(AOF_IMPLICIT, 32, REG_esi_id) +#define OP_edi AO_REGISTER(AOF_IMPLICIT, 32, REG_edi_id) /* mod r/m byte */ #define AOF_I386_MODRM 0x2 @@ -200,5 +208,14 @@ { "bsr", 0x0fbd, OP2F, OP_RMW_RW_R,OP_RMW_DW_R,AOT_NONE }, { "bsr", 0x0fbd, OP2F, OP_RMW_RW_R,OP_RMW_RW_R,AOT_NONE }, #endif +/* BSWAP 0x0fc8 +rd 2 */ +{ "bswap", 0x0fc8, OP2F, OP_eax, AOT_NONE, AOT_NONE }, +{ "bswap", 0x0fc9, OP2F, OP_ecx, AOT_NONE, AOT_NONE }, +{ "bswap", 0x0fca, OP2F, OP_edx, AOT_NONE, AOT_NONE }, +{ "bswap", 0x0fcb, OP2F, OP_ebx, AOT_NONE, AOT_NONE }, +{ "bswap", 0x0fcc, OP2F, OP_esp, AOT_NONE, AOT_NONE }, +{ "bswap", 0x0fcd, OP2F, OP_ebp, AOT_NONE, AOT_NONE }, +{ "bswap", 0x0fce, OP2F, OP_esi, AOT_NONE, AOT_NONE }, +{ "bswap", 0x0fcf, OP2F, OP_edi, AOT_NONE, AOT_NONE }, /* NOP */ { "nop", 0x90, OP1F, AOT_NONE, AOT_NONE, AOT_NONE }, diff --git a/src/arch/i486.c b/src/arch/i486.c new file mode 100644 index 0000000..3b530d7 --- /dev/null +++ b/src/arch/i486.c @@ -0,0 +1,79 @@ +/* $Id$ */ +/* Copyright (c) 2011 Pierre Pronchery */ +/* This file is part of DeforaOS Devel asm */ +/* 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 +#include "Asm.h" + + +/* i486 */ +/* private */ +/* types */ +/* register sizes */ +#define REG(name, size, id) REG_ ## name ## _size = size, +enum +{ +#include "i386.reg" + REG_size_count +}; +#undef REG + +/* register ids */ +#define REG(name, size, id) REG_ ## name ## _id = id, +enum +{ +#include "i386.reg" + REG_id_count +}; +#undef REG + + +/* variables */ +#define REG(name, size, id) { "" # name, size, id }, +static ArchRegister _i486_registers[] = +{ +#include "i386.reg" + { NULL, 0, 0 } +}; +#undef REG + +static ArchInstruction _i486_instructions[] = +{ +#include "i386.ins" +#include "i486.ins" +#include "common.ins" +#include "null.ins" +}; + + +/* functions */ +#include "i386.h" + + +/* public */ +/* variables */ +/* plug-in */ +ArchPlugin arch_plugin = +{ + NULL, + "i486", + NULL, + _i486_registers, + _i486_instructions, + _i386_write, + NULL +}; diff --git a/src/arch/i486.ins b/src/arch/i486.ins new file mode 100644 index 0000000..f4faa1a --- /dev/null +++ b/src/arch/i486.ins @@ -0,0 +1,10 @@ +/* instructions */ +/* BSWAP 0x0fc8 +rd 2 */ +{ "bswap", 0x0fc8, OP2F, OP_eax, AOT_NONE, AOT_NONE }, +{ "bswap", 0x0fc9, OP2F, OP_ecx, AOT_NONE, AOT_NONE }, +{ "bswap", 0x0fca, OP2F, OP_edx, AOT_NONE, AOT_NONE }, +{ "bswap", 0x0fcb, OP2F, OP_ebx, AOT_NONE, AOT_NONE }, +{ "bswap", 0x0fcc, OP2F, OP_esp, AOT_NONE, AOT_NONE }, +{ "bswap", 0x0fcd, OP2F, OP_ebp, AOT_NONE, AOT_NONE }, +{ "bswap", 0x0fce, OP2F, OP_esi, AOT_NONE, AOT_NONE }, +{ "bswap", 0x0fcf, OP2F, OP_edi, AOT_NONE, AOT_NONE }, diff --git a/src/arch/project.conf b/src/arch/project.conf index 1745cd1..067c56a 100644 --- a/src/arch/project.conf +++ b/src/arch/project.conf @@ -1,8 +1,8 @@ -targets=i386,sparc +targets=i386,i486,sparc cppflags_force=-I ../../include cflags_force=-W cflags=-Wall -fPIC -pedantic -dist=Makefile,common.ins,i386.ins,i386.reg,null.ins,sparc.ins,sparc.reg +dist=Makefile,common.ins,i386.h,i386.ins,i386.reg,i486.ins,null.ins,sparc.ins,sparc.reg [i386] type=plugin @@ -10,7 +10,15 @@ sources=i386.c install=$(LIBDIR)/asm/arch [i386.c] -depends=common.ins,null.ins,i386.ins,i386.reg +depends=common.ins,null.ins,i386.h,i386.ins,i386.reg + +[i486] +type=plugin +sources=i486.c +install=$(LIBDIR)/asm/arch + +[i486.c] +depends=common.ins,null.ins,i386.h,i386.ins,i386.reg,i486.ins [sparc] type=plugin diff --git a/test/Makefile b/test/Makefile index 650078f..7b71445 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,4 +1,4 @@ -TARGETS = i386.o sparc.o +TARGETS = i386.o i486.o sparc.o PREFIX = /usr/local DESTDIR = BINDIR = $(PREFIX)/bin @@ -15,17 +15,23 @@ all: $(TARGETS) i386.o_OBJS = i386.o i386.o_ASFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(ASFLAGS) -a i386 -f flat +i486.o_OBJS = i486.o +i486.o_ASFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(ASFLAGS) -a i486 -f flat + sparc.o_OBJS = sparc.o sparc.o_ASFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(ASFLAGS) -a sparc -f flat i386.o: i386.S ../src/asm $(AS) $(i386.o_ASFLAGS) -o i386.o i386.S +i486.o: i486.S ../src/asm + $(AS) $(i486.o_ASFLAGS) -o i486.o i486.S + sparc.o: sparc.S ../src/asm $(AS) $(sparc.o_ASFLAGS) -o sparc.o sparc.S clean: - $(RM) -- $(i386.o_OBJS) $(sparc.o_OBJS) + $(RM) -- $(i386.o_OBJS) $(i486.o_OBJS) $(sparc.o_OBJS) distclean: clean $(RM) -- $(TARGETS) diff --git a/test/i486.S b/test/i486.S new file mode 100644 index 0000000..0d3eb00 --- /dev/null +++ b/test/i486.S @@ -0,0 +1,11 @@ +/* $Id$ */ +.text + /* BSWAP */ + bswap %eax + bswap %ecx + bswap %edx + bswap %ebx + bswap %esp + bswap %ebp + bswap %esi + bswap %edi diff --git a/test/project.conf b/test/project.conf index 230b7ef..3c57589 100644 --- a/test/project.conf +++ b/test/project.conf @@ -1,4 +1,4 @@ -targets=i386.o,sparc.o +targets=i386.o,i486.o,sparc.o as=../src/asm dist=Makefile @@ -10,6 +10,14 @@ sources=i386.S asflags=-a i386 -f flat depends=../src/asm +[i486.o] +type=object +sources=i486.S + +[i486.S] +asflags=-a i486 -f flat +depends=../src/asm + [sparc.o] type=object sources=sparc.S