stm8-binutils-gdb/binutils_patches/0007-Added-gc-sections-and-...

784 lines
22 KiB
Diff

From 69776a7af5b7a3697c5d32f3265d2a8de8cb5b32 Mon Sep 17 00:00:00 2001
From: Xavier ASUS <xavi92psx@gmail.com>
Date: Tue, 29 Oct 2019 00:43:05 +0100
Subject: [PATCH 7/10] Added --gc-sections and hi8/lo8/hh8
---
bfd/elf32-stm8.c | 229 ++++++++++++++++++++++++----
bfd/libbfd.h | 3 +
bfd/reloc.c | 15 ++
gas/config/tc-stm8.c | 163 +++++++++++++++++---
gas/config/tc-stm8.h | 2 +-
include/elf/stm8.h | 3 +
include/opcode/stm8.h | 5 +-
opcodes/stm8-dis.c | 31 +++-
opcodes/stm8-opc.c | 6 +
9 files changed, 400 insertions(+), 57 deletions(-)
diff --git a/bfd/elf32-stm8.c b/bfd/elf32-stm8.c
index 37995553..5eb3c814 100644
--- a/bfd/elf32-stm8.c
+++ b/bfd/elf32-stm8.c
@@ -26,17 +26,16 @@
#include "elf-bfd.h"
#include "elf/stm8.h"
-//#include "elf32-avr.h"
#include "bfd_stdint.h"
bfd_reloc_status_type
bfd_elf_stm8_spec_reloc (bfd *abfd ATTRIBUTE_UNUSED,
- arelent *reloc_entry,
- asymbol *symbol,
- void *data ATTRIBUTE_UNUSED,
- asection *input_section,
- bfd *output_bfd,
- char **error_message ATTRIBUTE_UNUSED);
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void *data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED);
static reloc_howto_type elf32_stm8_howto_table_1[] =
{
@@ -96,7 +95,8 @@ static reloc_howto_type elf32_stm8_howto_table_1[] =
bfd_elf_generic_reloc, /* special_function */
"R_STM8_24", /* name */
FALSE, /* partial_inplace */
- 0xff000000, /* src_mask */
+ //0xff000000, /* src_mask */
+ 0x0, /* src_mask */
0x00ffffff, /* dst_mask */
FALSE), /* pcrel_offset */
@@ -142,30 +142,75 @@ static reloc_howto_type elf32_stm8_howto_table_1[] =
0x0, /* src_mask */
0xff, /* dst_mask */
TRUE), /* pcrel_offset */
+
+ /* lo 8 bit relocation. */
+ HOWTO (R_STM8_LO8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_STM8_LO8", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* hi 8 bit relocation. */
+ HOWTO (R_STM8_HI8, /* type */
+ 8, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_STM8_HI8", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* hh 8 bit relocation. */
+ HOWTO (R_STM8_HH8, /* type */
+ 16, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_STM8_HH8", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
};
//stupid bfd_elf_generic_reloc cant handle 24-bit relocations
//so we have to write our own...
bfd_reloc_status_type
bfd_elf_stm8_spec_reloc (bfd *abfd ATTRIBUTE_UNUSED,
- arelent *reloc_entry,
- asymbol *symbol,
- void *data ATTRIBUTE_UNUSED,
- asection *input_section ATTRIBUTE_UNUSED,
- bfd *output_bfd,
- char **error_message ATTRIBUTE_UNUSED)
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void *data ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
{
if (output_bfd != NULL
&& (symbol->flags & BSF_SECTION_SYM) == 0
&& (! reloc_entry->howto->partial_inplace
- || reloc_entry->addend == 0))
+ || reloc_entry->addend == 0))
{
reloc_entry->address += input_section->output_offset+1;
return bfd_reloc_ok;
}
if (output_bfd == NULL)
- return bfd_reloc_continue;
+ return bfd_reloc_continue;
reloc_entry->address += input_section->output_offset-1;
return bfd_reloc_continue;
}
@@ -203,7 +248,10 @@ static const struct elf32_stm8_reloc_map elf32_stm8_reloc_map[] =
{ BFD_RELOC_16, R_STM8_16 },
{ BFD_RELOC_24, R_STM8_24 },
{ BFD_RELOC_32, R_STM8_32 },
- { BFD_RELOC_8_PCREL, R_STM8_8_PCREL}
+ { BFD_RELOC_8_PCREL, R_STM8_8_PCREL},
+ { BFD_RELOC_STM8_LO8, R_STM8_LO8},
+ { BFD_RELOC_STM8_HI8, R_STM8_HI8},
+ { BFD_RELOC_STM8_HH8, R_STM8_HH8},
};
static reloc_howto_type *
@@ -235,12 +283,12 @@ elf32_stm8_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
static void
elf32_stm8_post_process_headers (bfd *abfd,
- struct bfd_link_info *info ATTRIBUTE_UNUSED)
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
// i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_STANDALONE;
// i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_ARM;
-// i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
+// i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
i_ehdrp->e_ident[EI_ABIVERSION] = 0;
}
@@ -253,33 +301,158 @@ elf32_stm8_modify_segment_map (bfd *abfd,
m = elf_seg_map (abfd);
while (m)
{
- m->includes_filehdr = 0;
- m->includes_phdrs = 0;
- m = m->next;
+ m->includes_filehdr = 0;
+ m->includes_phdrs = 0;
+ m = m->next;
}
return TRUE;
}
+static bfd_boolean
+elf32_stm8_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info,
+ bfd *input_bfd,
+ asection *input_section,
+ bfd_byte *contents,
+ Elf_Internal_Rela *relocs,
+ Elf_Internal_Sym *local_syms,
+ asection **local_sections)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+
+ symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ relend = relocs + input_section->reloc_count;
+
+ for (rel = relocs; rel < relend; rel ++)
+ {
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ struct elf_link_hash_entry *h;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+ const char *name;
+ int r_type;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ howto = elf32_stm8_howto_from_type(r_type);
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections [r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+
+ name = bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name);
+ if (name == NULL || name[0] == 0)
+ name = bfd_section_name (input_bfd, sec);
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc, warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+
+ name = h->root.root.string;
+ }
-#define elf_backend_post_process_headers elf32_stm8_post_process_headers
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (bfd_link_relocatable (info))
+ continue;
+
+ if (!howto)
+ {
+ (*info->callbacks->einfo)("%s unkown reloc type %lu\n", __FILE__, r_type);
+ return FALSE;
+ }
+
+#if 0
+ fprintf(stderr,"reloc %s offset=%4.4lx addend=%4.4lx name=%s\n", howto->name, rel->r_offset, rel->r_addend, name);
+#endif
+
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+
+ if (r != bfd_reloc_ok)
+ {
+ const char * msg = (const char *) NULL;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ (*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
+ break;
+
+ case bfd_reloc_undefined:
+ (*info->callbacks->undefined_symbol)
+ (info, name, input_bfd, input_section, rel->r_offset, TRUE);
+ break;
+
+ case bfd_reloc_outofrange:
+ msg = _("internal error: out of range error");
+ break;
+
+ case bfd_reloc_notsupported:
+ msg = _("internal error: unsupported relocation error");
+ break;
+
+ case bfd_reloc_dangerous:
+ msg = _("internal error: dangerous relocation");
+ break;
+
+ default:
+ msg = _("internal error: unknown error");
+ break;
+ }
+
+ if (msg)
+ (*info->callbacks->warning) (info, msg, name, input_bfd,
+ input_section, rel->r_offset);
+ }
+
+ }
+ return TRUE;
+}
+
+#define elf_backend_post_process_headers elf32_stm8_post_process_headers
#define elf_backend_modify_segment_map elf32_stm8_modify_segment_map
#define bfd_elf32_bfd_reloc_type_lookup elf32_stm8_reloc_type_lookup
#define bfd_elf32_bfd_reloc_name_lookup elf32_stm8_reloc_name_lookup
#define ELF_ARCH bfd_arch_stm8
-//#define ELF_TARGET_ID AVR_ELF_DATA
#define ELF_TARGET_ID GENERIC_ELF_DATA
#define ELF_MACHINE_CODE EM_STM8
-//#define ELF_OSABI ELFOSABI_STANDALONE
-//#define ELF_MACHINE_ALT1 EM_STM8_OLD
#define ELF_MAXPAGESIZE 1
-//#define TARGET_LITTLE_SYM stm8_elf32_vec
-//#define TARGET_LITTLE_NAME "elf32-stm8"
#define TARGET_BIG_SYM stm8_elf32_vec
#define TARGET_BIG_NAME "elf32-stm8"
#define elf_info_to_howto elf32_stm8_info_to_howto
#define elf_info_to_howto_rel NULL
+#define elf_backend_can_gc_sections 1
+#define elf_backend_relocate_section elf32_stm8_relocate_section
+#define bfd_elf32_bfd_link_hash_table_create _bfd_elf_link_hash_table_create
+#define bfd_elf32_bfd_final_link bfd_elf_gc_common_final_link
+
#include "elf32-target.h"
+
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index fca8c19e..edb2df8a 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -3189,6 +3189,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_WASM32_INDEX",
"BFD_RELOC_WASM32_PLT_SIG",
"BFD_RELOC_STM8_BIT_FLD",
+ "BFD_RELOC_STM8_LO8",
+ "BFD_RELOC_STM8_HI8",
+ "BFD_RELOC_STM8_HH8",
"@@overflow: BFD_RELOC_UNUSED@@",
};
#endif
diff --git a/bfd/reloc.c b/bfd/reloc.c
index c7b862aa..4ad743a2 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -7936,6 +7936,21 @@ ENUM
ENUMDOC
STM8 bit field immediate for BTJx, BCPL, BSET, BRES instruction.
+ENUM
+ BFD_RELOC_STM8_LO8
+ENUMDOC
+ STM8 extract LSB from word.
+
+ENUM
+ BFD_RELOC_STM8_HI8
+ENUMDOC
+ STM8 extract MSB from word.
+
+ENUM
+ BFD_RELOC_STM8_HH8
+ENUMDOC
+ STM8 extract MMSB from 24-bit address.
+
ENDSENUM
BFD_RELOC_UNUSED
CODE_FRAGMENT
diff --git a/gas/config/tc-stm8.c b/gas/config/tc-stm8.c
index 38fa5072..e670cb1d 100644
--- a/gas/config/tc-stm8.c
+++ b/gas/config/tc-stm8.c
@@ -26,6 +26,7 @@
#include <string.h>
#include <ctype.h>
#include "opcode/stm8.h"
+#include <string.h>
typedef enum {
OP_ILLEGAL = 0,
@@ -43,9 +44,31 @@ typedef enum {
OP_PTRW_Y,
OP_PTRE_X,
OP_PTRE_Y,
- OP_REGISTER
+ OP_REGISTER,
+ OP_HI8,
+ OP_LO8,
+ OP_HH8
} stm8_operand_t;
+typedef struct
+{
+ /* Name of the expression modifier allowed with .byte, .word, etc. */
+ const char *name;
+
+ /* Only allowed with n bytes of data. */
+ int nbytes;
+
+ /* Associated RELOC. */
+ bfd_reloc_code_real_type reloc;
+
+ /* Part of the error message. */
+ const char *error;
+
+ /* Internal operand. */
+ stm8_operand_t op;
+
+} exp_mod_data_t;
+
static struct hash_control *stm8_hash;
const char comment_chars[] = ";";
@@ -133,7 +156,7 @@ md_begin (void)
{
const struct stm8_opcodes_s *opcode;
stm8_hash = hash_new ();
-
+
/* Insert unique names into hash table. This hash table then provides a
quick index to the first opcode with a particular name in the opcode
table. */
@@ -198,6 +221,15 @@ md_begin (void)
}
+const exp_mod_data_t exp_mod_data[] =
+{
+ /* Default, must be first. */
+ { "", 0, BFD_RELOC_16, "", OP_ILLEGAL },
+ { "lo8", 1, BFD_RELOC_STM8_LO8, "`lo8' ", OP_LO8 },
+ { "hi8", 1, BFD_RELOC_STM8_HI8, "`hi8' ", OP_HI8 },
+ { "hh8", 1, BFD_RELOC_STM8_HH8, "`hi8' ", OP_HH8 },
+};
+
static inline char *
skip_space (char *s)
{
@@ -239,8 +271,6 @@ md_operand (expressionS * exp __attribute__((unused)))
void print_fixup (fixS *);
-
-
/* Attempt to simplify or eliminate a fixup. To indicate that a fixup
has been eliminated, set fix->fx_done. If fix->fx_addsy is non-NULL,
we will have to generate a reloc entry. */
@@ -335,6 +365,18 @@ md_apply_fix (fixS *fixP, valueT *valP, segT segment ATTRIBUTE_UNUSED)
fixP->fx_done = 1;
break;
+ case BFD_RELOC_STM8_LO8:
+ *buf = 0xff & val;
+ break;
+
+ case BFD_RELOC_STM8_HI8:
+ *buf = (0xff00 & val) >> 8;
+ break;
+
+ case BFD_RELOC_STM8_HH8:
+ *buf = (0xff0000 & val) >> 16;
+ break;
+
default:
printf(_("md_apply_fix: unknown r_type 0x%x\n"), fixP->fx_r_type);
abort ();
@@ -526,13 +568,13 @@ int read_arg_ptr(char *str, expressionS *exps)
char *s;
char *p;
char c;
-
+
if ((str[0]=='[') && (strstr(str,"]")))
{
s = str;
s++;
input_line_pointer=s;
-
+
/* first eat up .w and .e */
if ((p = strstr(s,".w]")))
{
@@ -545,11 +587,11 @@ int read_arg_ptr(char *str, expressionS *exps)
c = *p;
*p = 0;
}
-
+
expression(exps);
if (stm8_debug)
print_expr(exps);
-
+
/* restore c */
if (p)
*p = c;
@@ -615,7 +657,7 @@ int read_arg(char *str, expressionS *exps)
print_expr(exps);
return 1;
}
-
+
char strx[256];
strncpy(strx,str,sizeof(strx));
toupperstr(strx);
@@ -719,6 +761,50 @@ int read_arg(char *str, expressionS *exps)
exps->X_md=OP_OFF_SP;
return 1;
}
+ else
+ {
+ /* The first entry of exp_mod_data[] contains an entry if no
+ expression modifier is present. Skip it. */
+ size_t i;
+
+ for (i = 1; i < ARRAY_SIZE (exp_mod_data); i++)
+ {
+ const exp_mod_data_t *const pexp = &exp_mod_data[i];
+ const size_t len = strlen (pexp->name);
+ const int result = strncasecmp (str, pexp->name, len);
+
+ if (!result)
+ {
+ str += len;
+ while (isspace(*str))
+ str++;
+
+ if (*str == '(')
+ {
+ input_line_pointer = ++str;
+
+ expression(exps);
+
+ if (*input_line_pointer == ')')
+ {
+ input_line_pointer++;
+
+ exps->X_md = pexp->op;
+ return 1;
+ }
+ else
+ {
+ as_bad (_("`)' required"));
+ return 0;
+ }
+ }
+
+ input_line_pointer = str;
+
+ break;
+ }
+ }
+ }
char *p;
char c;
@@ -777,7 +863,7 @@ void stm8_bfd_out(struct stm8_opcodes_s op, expressionS exp[], int count, char *
int i;
int arg = 0;
int dir = 1;
-
+
/* if count is negative the arguments are reversed */
if (count < 0)
{
@@ -833,6 +919,21 @@ void stm8_bfd_out(struct stm8_opcodes_s op, expressionS exp[], int count, char *
case ST8_BIT_0:
fix_new_exp(frag_now, where-3, 1, &exp[arg], FALSE, BFD_RELOC_STM8_BIT_FLD);
break;
+ case ST8_HI8:
+ fix_new_exp(frag_now, where, 1, &exp[arg], FALSE, BFD_RELOC_STM8_HI8);
+ bfd_put_bits(0xaaaaaaaa, frag, 8, true);
+ frag+=1;
+ break;
+ case ST8_LO8:
+ fix_new_exp(frag_now, where, 1, &exp[arg], FALSE, BFD_RELOC_STM8_LO8);
+ bfd_put_bits(0xaaaaaaaa, frag, 8, true);
+ frag+=1;
+ break;
+ case ST8_HH8:
+ fix_new_exp(frag_now, where, 1, &exp[arg], FALSE, BFD_RELOC_STM8_HH8);
+ bfd_put_bits(0xaaaaaaaa, frag, 8, true);
+ frag+=1;
+ break;
default:
break;
}
@@ -945,6 +1046,18 @@ int cmpspec(stm8_addr_mode_t addr_mode[], expressionS exps[], int count)
if (addr_mode[i] == ST8_SHORTMEM)
continue;
break;
+ case OP_LO8:
+ if (addr_mode[i] == ST8_LO8)
+ continue;
+ break;
+ case OP_HI8:
+ if (addr_mode[i] == ST8_HI8)
+ continue;
+ break;
+ case OP_HH8:
+ if (addr_mode[i] == ST8_HH8)
+ continue;
+ break;
case OP_ILLEGAL:
as_fatal(_("BUG: OP_ILLEGAL"));
return 1;
@@ -989,22 +1102,22 @@ md_assemble (char *str)
for(i = 0; opcode[i].name != NULL; i++)
{
if (!strcmp(op, opcode[i].name))
- if(!cmpspec(opcode[i].constraints, exps, count))
- {
- int insn_size = stm8_compute_insn_size(opcode[i]);
- char *frag = frag_more(insn_size);
- int opcode_length = stm8_opcode_size(opcode[i].bin_opcode);
- bfd_put_bits(opcode[i].bin_opcode, frag, opcode_length * 8, true);
- frag += opcode_length;
-
- /* mov insn operands are reversed */
- if ((opcode[i].bin_opcode == 0x35) || (opcode[i].bin_opcode == 0x45) || (opcode[i].bin_opcode == 0x55))
+ if(!cmpspec(opcode[i].constraints, exps, count))
{
- count = -count;
+ int insn_size = stm8_compute_insn_size(opcode[i]);
+ char *frag = frag_more(insn_size);
+ int opcode_length = stm8_opcode_size(opcode[i].bin_opcode);
+ bfd_put_bits(opcode[i].bin_opcode, frag, opcode_length * 8, true);
+ frag += opcode_length;
+
+ /* mov insn operands are reversed */
+ if ((opcode[i].bin_opcode == 0x35) || (opcode[i].bin_opcode == 0x45) || (opcode[i].bin_opcode == 0x55))
+ {
+ count = -count;
+ }
+ stm8_bfd_out(opcode[i], exps, count, frag);
+ break;
}
- stm8_bfd_out(opcode[i], exps, count, frag);
- break;
- }
}
if(!opcode[i].name)
as_bad("Invalid instruction: %s", str_orig);
@@ -1028,7 +1141,7 @@ md_pcrel_from_section (fixS *fixp, segT sec)
&& (!S_IS_DEFINED (fixp->fx_addsy)
|| (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
return 0;
-
+
return fixp->fx_size + fixp->fx_where + fixp->fx_frag->fr_address;
//return fixp->fx_frag->fr_address+fixp->fx_frag->fr_fix;
return fixp->fx_frag->fr_address + fixp->fx_where;
diff --git a/gas/config/tc-stm8.h b/gas/config/tc-stm8.h
index 066e72ea..45c94d69 100644
--- a/gas/config/tc-stm8.h
+++ b/gas/config/tc-stm8.h
@@ -40,7 +40,7 @@
/* You should define this macro to be non-zero if the target is big
endian, and zero if the target is little endian. */
-#define TARGET_BYTES_BIG_ENDIAN 0
+#define TARGET_BYTES_BIG_ENDIAN 1
/* If you define this macro, GAS will warn about the use of
nonstandard escape sequences in a string. */
diff --git a/include/elf/stm8.h b/include/elf/stm8.h
index 4f703354..3468a575 100644
--- a/include/elf/stm8.h
+++ b/include/elf/stm8.h
@@ -33,6 +33,9 @@ START_RELOC_NUMBERS (elf_avr_reloc_type)
RELOC_NUMBER (R_STM8_24, 3)
RELOC_NUMBER (R_STM8_32, 4)
RELOC_NUMBER (R_STM8_8_PCREL, 5)
+ RELOC_NUMBER (R_STM8_HI8, 6)
+ RELOC_NUMBER (R_STM8_LO8, 7)
+ RELOC_NUMBER (R_STM8_HH8, 8)
END_RELOC_NUMBERS (R_STM8_max)
#endif /* _ELF_STM_H */
diff --git a/include/opcode/stm8.h b/include/opcode/stm8.h
index d131527d..18eb88a7 100644
--- a/include/opcode/stm8.h
+++ b/include/opcode/stm8.h
@@ -63,7 +63,10 @@ typedef enum {
ST8_LONGPTRW_Y,
ST8_LONGPTRE,
ST8_LONGPTRE_X,
- ST8_LONGPTRE_Y
+ ST8_LONGPTRE_Y,
+ ST8_HI8,
+ ST8_LO8,
+ ST8_HH8
} stm8_addr_mode_t;
struct stm8_opcodes_s
diff --git a/opcodes/stm8-dis.c b/opcodes/stm8-dis.c
index 2eee6306..906b8370 100644
--- a/opcodes/stm8-dis.c
+++ b/opcodes/stm8-dis.c
@@ -332,6 +332,33 @@ int stm8_operands(char *s, unsigned char buf[], stm8_addr_mode_t arg)
sprintf(s,"(0x%6.6x,Y)",val);
return 3;
break;
+ case ST8_HI8:
+ val = buf[0];
+ sym = find_symbol(val);
+ if (sym)
+ sprintf(s,"hi8(#%s)",sym);
+ else
+ sprintf(s,"hi8(#0x%2.2x)",val);
+ return 2;
+ break;
+ case ST8_LO8:
+ val = buf[0];
+ sym = find_symbol(val);
+ if (sym)
+ sprintf(s,"lo8(#%s)",sym);
+ else
+ sprintf(s,"lo8(#0x%2.2x)",val);
+ return 2;
+ break;
+ case ST8_HH8:
+ val = buf[0];
+ sym = find_symbol(val);
+ if (sym)
+ sprintf(s,"hh8(#%s)",sym);
+ else
+ sprintf(s,"hh8(#0x%4.4x)",val);
+ return 3;
+ break;
case ST8_END:
break;
}
@@ -389,8 +416,8 @@ int stm8_dis(bfd_vma addr, unsigned int op)
}
}
}
-
-
+
+
// c = ' ';
// for (j=0; j<5; j++, operand += dir)
// {
diff --git a/opcodes/stm8-opc.c b/opcodes/stm8-opc.c
index 9516d859..d16e7b60 100644
--- a/opcodes/stm8-opc.c
+++ b/opcodes/stm8-opc.c
@@ -489,6 +489,9 @@ const struct stm8_opcodes_s stm8_opcodes[] =
{"push", {ST8_REG_CC}, 0x8A},
{"push", {ST8_BYTE}, 0x4B},
{"push", {ST8_LONGMEM}, 0x3B},
+{"push", {ST8_HI8}, 0x4B},
+{"push", {ST8_LO8}, 0x4B},
+{"push", {ST8_HH8}, 0x4B},
//pushw
{"pushw", {ST8_REG_X}, 0x89},
{"pushw", {ST8_REG_Y}, 0x9089},
@@ -759,6 +762,8 @@ int stm8_compute_insn_size(struct stm8_opcodes_s opcode) {
case ST8_SHORTOFF_X:
case ST8_SHORTOFF_Y:
case ST8_SHORTOFF_SP:
+ case ST8_LO8:
+ case ST8_HI8:
ret++;
break;
case ST8_LONGPTRE_Y:
@@ -776,6 +781,7 @@ int stm8_compute_insn_size(struct stm8_opcodes_s opcode) {
case ST8_EXTMEM:
case ST8_EXTOFF_X:
case ST8_EXTOFF_Y:
+ case ST8_HH8:
ret += 3;
break;
case ST8_END:
--
2.17.1