diff options
| author | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-21 16:08:26 +0200 |
|---|---|---|
| committer | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-21 16:08:26 +0200 |
| commit | 9d8d485a0a3b869ad64bb745d102ab6cac0ba4a1 (patch) | |
| tree | 5428e47ddf776e9b56a2000e77396996f2ae1955 /src | |
| parent | de2840528859860ca242f7bde0cbd90d51984cf2 (diff) | |
Implemented --ffunction-sections
Interrupt vector must be placed on section .vectors, according to
the default linker script file.
Intermediate labels must be $-terminated so they are not listed by nm.
Diffstat (limited to 'src')
| -rw-r--r-- | src/SDCCglobl.h | 1 | ||||
| -rw-r--r-- | src/SDCCmain.c | 1 | ||||
| -rw-r--r-- | src/SDCCmem.h | 2 | ||||
| -rw-r--r-- | src/stm8/gen.c | 86 | ||||
| -rw-r--r-- | src/stm8/main.c | 12 |
5 files changed, 55 insertions, 47 deletions
diff --git a/src/SDCCglobl.h b/src/SDCCglobl.h index 89e33de..f8b41b3 100644 --- a/src/SDCCglobl.h +++ b/src/SDCCglobl.h @@ -329,6 +329,7 @@ struct options bool noOptsdccInAsm; /* Do not emit .optsdcc in asm */ bool oldralloc; /* Use old register allocator */ int gasOutput; /* Output assembly in GNU as format */ + int function_sections; /* Place each function into a separate section. Useful for link-time dead code elimination. */ }; /* forward definition for variables accessed globally */ diff --git a/src/SDCCmain.c b/src/SDCCmain.c index d83195a..affd5a1 100644 --- a/src/SDCCmain.c +++ b/src/SDCCmain.c @@ -174,6 +174,7 @@ static const OPTION optionsTable[] = { {'W', NULL, NULL, "Pass through options to the pre-processor (p), assembler (a) or linker (l)"}, {'S', NULL, &noAssemble, "Compile only; do not assemble or link"}, {0 , "--gas", &options.gasOutput, "Compile in GAS (GNU Assembler) format."}, + {0 , "--function-sections", &options.function_sections, "Place each function into a separate section. Useful for link-time dead code elimination."}, {'c', "--compile-only", &options.cc_only, "Compile and assemble, but do not link"}, {'E', "--preprocessonly", &preProcOnly, "Preprocess only, do not compile"}, {0, "--c1mode", &options.c1mode, "Act in c1 mode. The standard input is preprocessed code, the output is assembly code."}, diff --git a/src/SDCCmem.h b/src/SDCCmem.h index 8e1bc56..7ee2728 100644 --- a/src/SDCCmem.h +++ b/src/SDCCmem.h @@ -60,7 +60,7 @@ extern FILE *junkFile; #define BIT_NAME port->mem.bit_name #define REG_NAME port->mem.reg_name #define STATIC_NAME port->mem.static_name -#define HOME_NAME (options.gasOutput ? ".text.interrupt_vector" : port->mem.home_name) +#define HOME_NAME (options.gasOutput ? ".vectors" : port->mem.home_name) #define OVERLAY_NAME port->mem.overlay_name #define CONST_NAME (options.gasOutput ? ".rodata" : port->mem.const_name) #define CABS_NAME port->mem.cabs_name diff --git a/src/stm8/gen.c b/src/stm8/gen.c index 7bf8c22..ff195d9 100644 --- a/src/stm8/gen.c +++ b/src/stm8/gen.c @@ -1094,7 +1094,7 @@ aopOp (operand *op, const iCode *ic) } /* None of the above, which only leaves temporaries. */ - { + { bool completely_in_regs = TRUE; bool completely_on_stack = TRUE; asmop *aop = newAsmop (AOP_REGSTK); @@ -1397,7 +1397,7 @@ adjustStack (int n, bool a_free, bool x_free, bool y_free) else { emit2 (n > 0 ? "addw" : "sub", "sp, #%d", abs (n)); - cost (2, 1); + cost (2, 1); G.stack.pushed -= n; updateCFA (); n -= n; @@ -1513,7 +1513,7 @@ genCopyStack (asmop *result, int roffset, asmop *source, int soffset, int n, boo i++; continue; } - cost (4, 4); + cost (4, 4); assigned[i] = TRUE; assigned[i + 1] = TRUE; (*size) -= 2; @@ -2035,7 +2035,7 @@ skip_byte: wassertl_bt (0, "Unimplemented."); cost (180, 180); return; - } + } // Copy (stack-to-stack) what we can with whatever free regs we have now. a_free = a_dead; @@ -2138,7 +2138,7 @@ skip_byte: i++; } else - { + { cheapMove (result, roffset + i, ASMOP_ZERO, 0, !a_free); assigned[i] = TRUE; if (aopInReg (result, roffset + i, A_IDX)) @@ -2452,9 +2452,9 @@ genNot (const iCode *ic) { emit3 (A_CLR, ASMOP_A, 0); emit3 (A_RLC, ASMOP_A, 0); - + cheapMove (result->aop, 0, ASMOP_A, 0, false); - + for (i = 1; i < result->aop->size; i++) cheapMove (result->aop, 0, ASMOP_ZERO, 0, true); } @@ -2730,10 +2730,10 @@ genSub (const iCode *ic, asmop *result_aop, asmop *left_aop, asmop *right_aop) if (aopInReg (result_aop, i, A_IDX)) result_in_a = TRUE; - + i++; } - else if (!started && i + 1 < size && (y_free || aopInReg(left_aop, i, Y_IDX) && regDead (Y_IDX, ic)) && + else if (!started && i + 1 < size && (y_free || aopInReg(left_aop, i, Y_IDX) && regDead (Y_IDX, ic)) && (aopOnStack (result_aop, i, 2) || result_aop->type == AOP_DIR) && (aopOnStack (left_aop, i, 2) || aopInReg(left_aop, i, Y_IDX) || left_aop->type == AOP_DIR) && (aopOnStackNotExt (right_aop, i, 2) || right_aop->type == AOP_LIT || right_aop->type == AOP_IMMD || right_aop->type == AOP_DIR && i + 1 < right_aop->size)) @@ -2753,7 +2753,7 @@ genSub (const iCode *ic, asmop *result_aop, asmop *left_aop, asmop *right_aop) started = TRUE; i += 2; } - else if (!started && right_aop->type == AOP_LIT && + else if (!started && right_aop->type == AOP_LIT && (aopInReg (left_aop, i, XH_IDX) && aopInReg (result_aop, i, XH_IDX) || aopInReg (left_aop, i, YH_IDX) && aopInReg (result_aop, i, YH_IDX))) { emit2 ("subw", "%s, #%d", aopInReg (left_aop, i, YH_IDX) ? "y" : "x", byteOfVal (right_aop->aopu.aop_lit, i) << 8); @@ -2767,7 +2767,7 @@ genSub (const iCode *ic, asmop *result_aop, asmop *left_aop, asmop *right_aop) emit2 ("subw", "%s, #%d", aopInReg (left_aop, i, YL_IDX) ? "y" : "x", byteOfVal (right_aop->aopu.aop_lit, i)); cost (3 + aopInReg (left_aop, i, YL_IDX), 2); started = TRUE; - i++; + i++; } else if (!started && i == size - 1 && aopOnStackNotExt (right_aop, i, 1) && (aopInReg (left_aop, i, XL_IDX) && aopInReg (result_aop, i, XL_IDX) && xh_free || aopInReg (left_aop, i, YL_IDX) && aopInReg (result_aop, i, YL_IDX) && yh_free)) @@ -2847,7 +2847,7 @@ genSub (const iCode *ic, asmop *result_aop, asmop *left_aop, asmop *right_aop) if (aopInReg (result_aop, i, A_IDX)) result_in_a = TRUE; - + i++; } } @@ -3154,7 +3154,7 @@ genCall (const iCode *ic) else { genMove (ASMOP_X, left->aop, TRUE, TRUE, TRUE); - + emit2 ("call", "(x)"); cost (1, 4); } @@ -3265,7 +3265,7 @@ genCall (const iCode *ic) aopOp (IC_RESULT (ic), ic); - size = !half ? IC_RESULT (ic)->aop->size : (IC_RESULT (ic)->aop->size > 2 ? 2 : IC_RESULT (ic)->aop->size); + size = !half ? IC_RESULT (ic)->aop->size : (IC_RESULT (ic)->aop->size > 2 ? 2 : IC_RESULT (ic)->aop->size); wassert (getSize (ftype->next) >= 1 && getSize (ftype->next) <= 4); @@ -3358,6 +3358,14 @@ genFunction (iCode *ic) emit2 (";", " function %s", sym->name); emit2 (";", "-----------------------------------------"); + if (options.function_sections && options.gasOutput) + { + char name[256]; + + snprintf(name, sizeof name, "%s.%s", CODE_NAME, sym->name); + emit2(".section", " %s", name); + } + D (emit2 (";", stm8_assignment_optimal ? "Register assignment is optimal." : "Register assignment might be sub-optimal.")); D (emit2 (";", "Stack space usage: %d bytes.", sym->stack)); @@ -3451,7 +3459,7 @@ genEndFunction (iCode *ic) /* if debug then send end of function */ if (options.debug && currFunc && !regalloc_dry_run) debugFile->writeEndFunction (currFunc, ic, 1); - + emit2 ("iret", ""); cost (1, 11); } @@ -3756,7 +3764,7 @@ genPlus (const iCode *ic) leftop = left->aop; rightop = right->aop; } - + for (i = 0, started = FALSE; i < size;) // Todo: 16-bit operation in dead source might be cheaper than add. { bool a_free = regDead (A_IDX, ic) && leftop->regs[A_IDX] <= i && rightop->regs[A_IDX] <= i && !result_in_a || pushed_a; @@ -3815,7 +3823,7 @@ genPlus (const iCode *ic) aopOnStack (leftop, i, size - i - 2) && aopOnStack (leftop, i, size - i - 2) && aopInReg (result->aop, size - 2, Y_IDX) && aopInReg (result->aop, size - 2, Y_IDX)) && result->aop->aopu.bytes[i].byteu.stk == leftop->aopu.bytes[i].byteu.stk || aopOnStack (leftop, i + 2, size - i - 2) && aopOnStack (leftop, i + 2, size - i - 2) && aopInReg (result->aop, i, Y_IDX) && aopInReg (result->aop, i, Y_IDX) && result->aop->aopu.bytes[i + 2].byteu.stk == leftop->aopu.bytes[i + 2].byteu.stk || - size - i == 4 && + size - i == 4 && (aopInReg (leftop, i, Y_IDX) && aopInReg (result->aop, i, Y_IDX) && aopInReg (leftop, i + 2, X_IDX) && aopInReg (result->aop, i + 2, X_IDX) || aopInReg (leftop, i, X_IDX) && aopInReg (result->aop, i, X_IDX) && aopInReg (leftop, i + 2, Y_IDX) && aopInReg (result->aop, i + 2, Y_IDX)))) { if(!endlbl && !regalloc_dry_run) @@ -3891,7 +3899,7 @@ genPlus (const iCode *ic) started = TRUE; i += 2; } - else if (!started && i + 1 < size && (y_free || aopInReg(leftop, i, Y_IDX) && regDead (Y_IDX, ic)) && + else if (!started && i + 1 < size && (y_free || aopInReg(leftop, i, Y_IDX) && regDead (Y_IDX, ic)) && (aopOnStack (result->aop, i, 2) || result->aop->type == AOP_DIR) && (aopOnStack (leftop, i, 2) || aopInReg(leftop, i, Y_IDX) || leftop->type == AOP_DIR) && (aopOnStackNotExt (rightop, i, 2) || rightop->type == AOP_LIT || rightop->type == AOP_IMMD || rightop->type == AOP_DIR && i + 1 < rightop->size)) @@ -4827,7 +4835,7 @@ genCmp (const iCode *ic, iCode *ifx) cheapMove (ASMOP_A, 0, left->aop, i, FALSE); right_stacked = stack_aop (right->aop, i, &right_offset); - + if (right_stacked || aopInReg (right->aop, i, A_IDX)) { emit2 (started ? "sbc" : "cp", "a, (%d, sp)", right_stacked ? right_offset : 1); @@ -4867,7 +4875,7 @@ _genCmp_1: case 20: /* special cases by genCmpTop () */ emit2 ("jrne", "%05d$", labelKey2num (tlbl1->key)); break; - default: /* normal cases */ + default: /* normal cases */ emit2 (branchInstCmp (opcode, sign, FALSE), "%05d$", labelKey2num (tlbl1->key)); break; } @@ -5666,7 +5674,7 @@ genAnd (const iCode *ic, iCode *ifx) } for (i = 0; i < size;) - { + { // Cases that don't need a free a. if (omitbyte == i) { @@ -5747,7 +5755,7 @@ genAnd (const iCode *ic, iCode *ifx) result_in_a |= new_in_a; i = j; } - else if (aopIsLitVal (right->aop, i, 1, 0xff)) + else if (aopIsLitVal (right->aop, i, 1, 0xff)) { bool new_in_a = FALSE; for(j = i; j < size && j != omitbyte && aopIsLitVal (right->aop, j, 1, 0xff); j++) @@ -5951,7 +5959,7 @@ genLeftShiftLiteral (operand *left, operand *right, operand *result, const iCode { std_bytes = shCount * 2; std_cycles = shCount; - } + } else if (aopInReg (shiftop, 0, YH_IDX)) { std_bytes = shCount * 5; @@ -6052,7 +6060,7 @@ std: i++; } } - + genMove (result->aop, shiftop, regDead (A_IDX, ic), regDead (X_IDX, ic), regDead (Y_IDX, ic)); @@ -6222,7 +6230,7 @@ postshift: if (pushed_a) pop (ASMOP_A, 0, 1); genMove (result->aop, shiftop, false, regDead (X_IDX, ic), regDead (Y_IDX, ic)); - } + } freeAsmop (left); freeAsmop (result); @@ -6403,7 +6411,7 @@ genRightShiftLiteral (operand *left, operand *right, operand *result, const iCod // Use swap a where beneficial. if (!sign && size == 1 && aopRS (shiftop) && !aopOnStack (shiftop, 0, 1) && !(aopInReg (shiftop, 0, XL_IDX) && xh_zero) && - !(aopInReg (shiftop, 0, YL_IDX) && yh_zero && shCount <= 3)) + !(aopInReg (shiftop, 0, YL_IDX) && yh_zero && shCount <= 3)) { swap_to_a (shiftop->aopu.bytes[0].byteu.reg->rIdx); if (shCount >= 4) @@ -6494,7 +6502,7 @@ genRightShiftLiteral (operand *left, operand *right, operand *result, const iCod } if (pushed_sign) pop (ASMOP_A, 0, 1); - + if (!regDead (A_IDX, ic)) pop (ASMOP_A, 0, 1); } @@ -6774,7 +6782,7 @@ genPointerGet (const iCode *ic) int blen, bstr; bool bit_field = IS_BITVAR (getSpec (operandType (result))); symbol *const tlbl = ((regalloc_dry_run || !bit_field) ? 0 : newiTempLabel (NULL)); - + blen = bit_field ? SPEC_BLEN (getSpec (operandType (result))) : 0; bstr = bit_field ? SPEC_BSTR (getSpec (operandType (result))) : 0; @@ -6845,7 +6853,7 @@ genPointerGet (const iCode *ic) if (use_y ? !(regDead (Y_IDX, ic) || aopInReg (left->aop, 0, Y_IDX)) : !(regDead (X_IDX, ic) || aopInReg (left->aop, 0, X_IDX))) // Preferred index register is not free. { // Try to free an index register. - if (result->aop->regs[XL_IDX] < 0 && result->aop->regs[XH_IDX] < 0) + if (result->aop->regs[XL_IDX] < 0 && result->aop->regs[XH_IDX] < 0) { push (ASMOP_X, 0, 2); pushed_x = true; @@ -6947,7 +6955,7 @@ genPointerGet (const iCode *ic) } if (bit_field && blen <= 8 && !SPEC_USIGN (getSpec (operandType (result)))) // Sign extension for partial byte of signed bit-field - { + { emit2 ("bcp", "a, #0x%02x", 0x80 >> (8 - blen)); cost (2, 1); if (tlbl) @@ -7056,7 +7064,7 @@ genPointerSet (iCode *ic) int blen, bstr; bool bit_field = IS_BITVAR (getSpec (operandType (right))) || IS_BITVAR (getSpec (operandType (left))); int cache_l = -1, cache_h = -1/*, cache_a = -1*/; - + blen = bit_field ? (SPEC_BLEN (getSpec (operandType (IS_BITVAR (getSpec (operandType (right))) ? right : left)))) : 0; bstr = bit_field ? (SPEC_BSTR (getSpec (operandType (IS_BITVAR (getSpec (operandType (right))) ? right : left)))) : 0; @@ -7098,7 +7106,7 @@ genPointerSet (iCode *ic) normal_cycles += 2; i++; } - } + } if (!regDead (X_IDX, ic)) { @@ -7697,7 +7705,7 @@ genCast (const iCode *ic) { if (!regDead (A_IDX, ic)) push (ASMOP_A, 0, 1); - + emit3w (A_NEGW, right->aop, 0); cost (aopInReg (right->aop, 0, X_IDX) ? 1 : 2, 2); emit3 (A_CLR, ASMOP_A, 0); @@ -7738,7 +7746,7 @@ genCast (const iCode *ic) { right_stacked = ASMOP_A; right_offset = 0; - } + } if (!offset && aopInReg (right->aop, offset, A_IDX)) { @@ -7797,7 +7805,7 @@ genCast (const iCode *ic) cost (2, 2); // 2 for cycle cost is just an estimate; it also ignores pipelining. emit3w_o (A_DECW, result->aop, offset, 0, 0); emitLabel (tlbl); - + goto release; } @@ -7809,7 +7817,7 @@ genCast (const iCode *ic) cheapMove (ASMOP_A, 0, result->aop, right->aop->size - 1, FALSE); emit3 (A_RLC, ASMOP_A, 0); - + if (size == 2 && (aopInReg (result->aop, offset, X_IDX) || aopInReg (result->aop, offset, Y_IDX))) // Faster when just setting 16-bit reg. { @@ -8152,7 +8160,7 @@ genSTM8Code (iCode *lic) { iCode *ic; int clevel = 0; - int cblock = 0; + int cblock = 0; int cln = 0; regalloc_dry_run = FALSE; @@ -8166,9 +8174,9 @@ genSTM8Code (iCode *lic) for (ic = lic; ic; ic = ic->next) { initGenLineElement (); - + genLine.lineElement.ic = ic; - + if (ic->level != clevel || ic->block != cblock) { if (options.debug) diff --git a/src/stm8/main.c b/src/stm8/main.c index 424d4cb..dbef2a8 100644 --- a/src/stm8/main.c +++ b/src/stm8/main.c @@ -281,22 +281,22 @@ stm8_genInitStartup (FILE *of) "_start:\n" "\t; Zeroing .bss\n" "\tldw x, __bss_start\n" - "\t$0:\n" + "0$:\n" "\tclr (x)\n" "\tincw x\n" "\tcpw x, __bss_end\n" - "\tjrne $0\n" + "\tjrne 0$\n" "\t; Copying .data from ROM to RAM\n" "\t; Calculate .data section size\n" "\tldw x, __data_load_start\n" "\tldw y, __data_start\n" - "\t$1:\n" + "1$:\n" "\tld a, (x)\n" "\tld (y), a\n" "\tincw x\n" "\tincw y\n" "\tcpw y, _edata\n" - "\tjrne $1\n"); + "\tjrne 1$\n"); } } @@ -308,9 +308,7 @@ stm8_genIVT(struct dbuf_s * oBuf, symbol ** intTable, int intCount) int i; if (options.gasOutput) - { - dbuf_tprintf(oBuf, "!area\n", ".vectors"); - } + dbuf_tprintf(oBuf, "\tint __interrupt_vect ; reset\n"); else dbuf_tprintf(oBuf, "\tint s_GSINIT ; reset\n"); |
