Line 1703... |
Line 1703... |
esac
|
esac
|
|
|
# If we aren't building newlib, then don't build libgloss, since libgloss
|
# If we aren't building newlib, then don't build libgloss, since libgloss
|
diff -Naur '--exclude=*.swp' binutils-2.27/gas/config/tc-zip.c binutils-2.27-zip/gas/config/tc-zip.c
|
diff -Naur '--exclude=*.swp' binutils-2.27/gas/config/tc-zip.c binutils-2.27-zip/gas/config/tc-zip.c
|
--- binutils-2.27/gas/config/tc-zip.c 1969-12-31 19:00:00.000000000 -0500
|
--- binutils-2.27/gas/config/tc-zip.c 1969-12-31 19:00:00.000000000 -0500
|
+++ binutils-2.27-zip/gas/config/tc-zip.c 2017-03-08 17:57:01.048791909 -0500
|
+++ binutils-2.27-zip/gas/config/tc-zip.c 2017-03-15 23:03:15.801504568 -0400
|
@@ -0,0 +1,3329 @@
|
@@ -0,0 +1,3340 @@
|
+////////////////////////////////////////////////////////////////////////////////
|
+////////////////////////////////////////////////////////////////////////////////
|
+//
|
+//
|
+// Filename: tc-zip.c
|
+// Filename: tc-zip.c
|
+//
|
+//
|
+// Project: Zip CPU backend for GNU Binutils
|
+// Project: Zip CPU backend for GNU Binutils
|
Line 2463... |
Line 2463... |
+
|
+
|
+static const char *zip_parse_reg(const char *str, ZIP_REG *regid) {
|
+static const char *zip_parse_reg(const char *str, ZIP_REG *regid) {
|
+ const char *ustr = str;
|
+ const char *ustr = str;
|
+ int userreg = 0;
|
+ int userreg = 0;
|
+
|
+
|
|
+ if ((!str)||(str[0]=='\0'))
|
|
+ return "No register given";
|
+ ustr = zip_skip_white_spaces(str);
|
+ ustr = zip_skip_white_spaces(str);
|
+
|
+
|
+ if (toupper(ustr[0]) == 'U') {
|
+ if (toupper(ustr[0]) == 'U') {
|
+ ustr = str+1;
|
+ ustr = str+1;
|
+ userreg = 0x10;
|
+ userreg = 0x10;
|
Line 3302... |
Line 3304... |
+ // form implies a PC relative addressing, which
|
+ // form implies a PC relative addressing, which
|
+ // may not be clear from the operands given
|
+ // may not be clear from the operands given
|
+ if (NULL != right)
|
+ if (NULL != right)
|
+ err = "Instruction opcode expects only one operand";
|
+ err = "Instruction opcode expects only one operand";
|
+ else {
|
+ else {
|
+ if ((NULL == strchr(left,'('))
|
+ if ((NULL == left)||(left[0] == '\0')) {
|
|
+ err = "No address given";
|
|
+ } else if ((NULL == strchr(left,'('))
|
+ &&(NULL == strchr(left,'+'))) {
|
+ &&(NULL == strchr(left,'+'))) {
|
+ char *longerstr = (char *)xmalloc(strlen(left)+6);
|
+ char *longerstr = (char *)xmalloc(strlen(left)+6);
|
+ // If not stated, assume PC relative
|
+ // If not stated, assume PC relative
|
+ strcpy(longerstr,left);
|
+ strcpy(longerstr,left);
|
+ strcat(longerstr, "(PC)");
|
+ strcat(longerstr, "(PC)");
|
Line 3638... |
Line 3642... |
+ // Prohibit moves to/from user regs to merge
|
+ // Prohibit moves to/from user regs to merge
|
+ if ((opa == ZIPO_MOV)&&(a & 0x44000))
|
+ if ((opa == ZIPO_MOV)&&(a & 0x44000))
|
+ return 0;
|
+ return 0;
|
+ if ((opb == ZIPO_MOV)&&(b & 0x44000))
|
+ if ((opb == ZIPO_MOV)&&(b & 0x44000))
|
+ return 0;
|
+ return 0;
|
|
+
|
+ imma = zip_non_cis_immediate(a);
|
+ imma = zip_non_cis_immediate(a);
|
+ immb = zip_non_cis_immediate(b);
|
+ immb = zip_non_cis_immediate(b);
|
+
|
+
|
+ if (!fits_within(8,imma)) {
|
+ if (!fits_within(8,imma)) {
|
+ // fprintf(stderr, "As immediate is out of range\n");
|
+ // fprintf(stderr, "As immediate is out of range\n");
|
Line 3659... |
Line 3664... |
+
|
+
|
+ switch(opa) {
|
+ switch(opa) {
|
+ case ZIPO_MOV:
|
+ case ZIPO_MOV:
|
+ if (!fits_within(3,imma))
|
+ if (!fits_within(3,imma))
|
+ return 0;
|
+ return 0;
|
+ if (aareg == ZIP_CC)
|
+ // Prohibit a MOV x(PC),Ry to move into a first
|
|
+ // instruction position. While the CPU supports it,
|
|
+ // making sure x remains valid isn't yet supported
|
|
+ // here.
|
|
+ if ((ZIP_PC == aareg)||(ZIP_CC == aareg))
|
+ return 0;
|
+ return 0;
|
+ break;
|
+ break;
|
+ case ZIPO_LDI: case ZIPO_LDIn:
|
+ case ZIPO_LDI: case ZIPO_LDIn:
|
+ if (!fits_within(8,imma))
|
+ if (!fits_within(8,imma))
|
+ return 0;
|
+ return 0;
|
Line 3971... |
Line 3980... |
+ this_segment, insn->i_imm);
|
+ this_segment, insn->i_imm);
|
+#endif
|
+#endif
|
+ switch(insn->i_op) {
|
+ switch(insn->i_op) {
|
+ case ZIPO_LDI: // May or may not be conditional
|
+ case ZIPO_LDI: // May or may not be conditional
|
+ if ((sym_known)&&(this_segment)
|
+ if ((sym_known)&&(this_segment)
|
+ &&(fits_within(13,immv+symv-fragP->fr_address-insn->i_rp->r_fr_offset-sizeof(uint32_t)))) {
|
+ &&(fits_within(15,immv+symv-fragP->fr_address-insn->i_rp->r_fr_offset-sizeof(uint32_t)))) {
|
+ // Turn this into a MOV x(PC),Rx
|
+ // Turn this into a MOV x(PC),Rx
|
|
+ //
|
|
+ // Although moves can normally only handle 13 bits,
|
|
+ // when the immediate is an offset to the PC, the bottom
|
|
+ // two bits are always zero, and so the immediate
|
|
+ // gets an extra two free bits--hence the test for
|
|
+ // fitting into 15 bits above.
|
+ insn->i_breg = ZIP_PC;
|
+ insn->i_breg = ZIP_PC;
|
+ insn->i_op = ZIPO_MOV;
|
+ insn->i_op = ZIPO_MOV;
|
+ insn->i_naux = 0;
|
+ insn->i_naux = 0;
|
+ zip_assemble_insn_words(fragP, seg, insn, relax_state,
|
+ zip_assemble_insn_words(fragP, seg, insn, relax_state,
|
+ stretch, pzipm);
|
+ stretch, pzipm);
|
Line 3985... |
Line 4000... |
+ }
|
+ }
|
+
|
+
|
+ // 0.111.x111.11
|
+ // 0.111.x111.11
|
+ insn->i_aux[0] = 0x7fc00000; // NOOP -- if never used.
|
+ insn->i_aux[0] = 0x7fc00000; // NOOP -- if never used.
|
+ immv += symv;
|
+ immv += symv;
|
+ if (((!insn->i_rp)||(sym_known))
|
+ if ((!insn->i_rp)&&(insn->i_cnd == ZIPC_ALWAYS)
|
+ &&(insn->i_cnd == ZIPC_ALWAYS)
|
|
+ &&(fits_within(23, immv))) {
|
+ &&(fits_within(23, immv))) {
|
+ insn->i_naux = 0;
|
+ insn->i_naux = 0;
|
+ insn->i_code = LDIOP(immv,insn->i_areg);
|
+ insn->i_code = LDIOP(immv,insn->i_areg);
|
+ } else if (((!insn->i_rp)||(sym_known))
|
+ } else if (((!insn->i_rp)||(sym_known))
|
+ &&(fits_within(18, zip_brev(immv)))) {
|
+ &&(fits_within(18, zip_brev(immv)))) {
|
Line 4003... |
Line 4017... |
+ zip_brev(immv),
|
+ zip_brev(immv),
|
+ insn->i_areg&0x0f);
|
+ insn->i_areg&0x0f);
|
+ if (insn->i_rp)
|
+ if (insn->i_rp)
|
+ insn->i_rp->r_type = BFD_RELOC_NONE;
|
+ insn->i_rp->r_type = BFD_RELOC_NONE;
|
+// 0000 1110 0000 0000 0000 0000 0100 0000
|
+// 0000 1110 0000 0000 0000 0000 0100 0000
|
+ } else if (((!insn->i_rp)||(sym_known))
|
|
+ &&(insn->i_cnd == ZIPC_ALWAYS)
|
|
+ &&(fits_within(23, immv))) {
|
|
+ insn->i_naux = 0;
|
|
+ insn->i_code = LDIOP(immv,insn->i_areg);
|
|
+ } else if ((zip_param_use_machine)&&(pzipm)&&((!insn->i_rp)||(sym_known))
|
+ } else if ((zip_param_use_machine)&&(pzipm)&&((!insn->i_rp)||(sym_known))
|
+ &&(pzipm->r[insn->i_areg].m_known)
|
+ &&(pzipm->r[insn->i_areg].m_known)
|
+ &&(0==((immv^pzipm->r[insn->i_areg].m_value)
|
+ &&(0==((immv^pzipm->r[insn->i_areg].m_value)
|
+ & 0x0ffff0000))) {
|
+ & 0x0ffff0000))) {
|
+ // Replace LDI with LDILO
|
+ // Replace LDI with LDILO
|
Line 4836... |
Line 4845... |
+ // is resolved. It is useful for PC relative addressing, as well as
|
+ // is resolved. It is useful for PC relative addressing, as well as
|
+ // instructions giving offsets to symbols, such as LDI .x+50,R0.
|
+ // instructions giving offsets to symbols, such as LDI .x+50,R0.
|
+ relP->addend = fixP->fx_offset;
|
+ relP->addend = fixP->fx_offset;
|
+ if (fixP->fx_r_type == BFD_RELOC_ZIP_OPB_PCREL)
|
+ if (fixP->fx_r_type == BFD_RELOC_ZIP_OPB_PCREL)
|
+ relP->addend -= 4;
|
+ relP->addend -= 4;
|
|
+ else if (fixP->fx_r_type == BFD_RELOC_ZIP_MOV_PCREL)
|
|
+ relP->addend -= 4;
|
+#ifdef ZIP_DEBUG
|
+#ifdef ZIP_DEBUG
|
+ fprintf(stderr, "ADDEND = %08lx\n", relP->addend);
|
+ fprintf(stderr, "ADDEND = %08lx\n", relP->addend);
|
+#endif
|
+#endif
|
+ relP->howto = bfd_reloc_type_lookup(stdoutput, fixP->fx_r_type);
|
+ relP->howto = bfd_reloc_type_lookup(stdoutput, fixP->fx_r_type);
|
+ if (! relP->howto) {
|
+ if (! relP->howto) {
|