From f2bd3a977d105f8a4ee3f4c86fe8daf52f629495 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 30 May 2012 16:47:56 -0400 Subject: [PATCH] cmd/6l, cmd/8l, cmd/5l: add AUNDEF instruction On 6l and 8l, this is a real instruction, guaranteed to cause an 'undefined instruction' exception. On 5l, we simulate it as BL to address 0. The plan is to use it as a signal to the linker that this point in the instruction stream cannot be reached (hence the changes to nofollow). This will help the compiler explain that panicindex and friends do not return without having to put a list of these functions in the linker. R=ken2 CC=golang-dev https://golang.org/cl/6255064 --- src/cmd/5a/lex.c | 1 + src/cmd/5l/5.out.h | 2 ++ src/cmd/5l/asm.c | 9 +++++++++ src/cmd/5l/optab.c | 2 ++ src/cmd/5l/pass.c | 6 +++--- src/cmd/5l/span.c | 1 + src/cmd/6a/lex.c | 1 + src/cmd/6l/6.out.h | 2 ++ src/cmd/6l/optab.c | 2 ++ src/cmd/6l/pass.c | 1 + src/cmd/8a/lex.c | 1 + src/cmd/8l/8.out.h | 2 ++ src/cmd/8l/optab.c | 2 ++ src/cmd/8l/pass.c | 1 + 14 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/cmd/5a/lex.c b/src/cmd/5a/lex.c index 252a282a05..e569fe62d3 100644 --- a/src/cmd/5a/lex.c +++ b/src/cmd/5a/lex.c @@ -405,6 +405,7 @@ struct "MRC", LTYPEJ, 1, "PLD", LTYPEPLD, APLD, + "UNDEF", LTYPEE, AUNDEF, 0 }; diff --git a/src/cmd/5l/5.out.h b/src/cmd/5l/5.out.h index 08a60d0642..3c726e924b 100644 --- a/src/cmd/5l/5.out.h +++ b/src/cmd/5l/5.out.h @@ -185,6 +185,8 @@ enum as ASTREXD, APLD, + + AUNDEF, ALAST, }; diff --git a/src/cmd/5l/asm.c b/src/cmd/5l/asm.c index c8e50305c6..22695b0716 100644 --- a/src/cmd/5l/asm.c +++ b/src/cmd/5l/asm.c @@ -1791,6 +1791,15 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p- o1 |= (-p->from.offset) & 0xfff; } else o1 |= p->from.offset & 0xfff; + case 96: /* UNDEF */ + // This is supposed to be something that stops execution. + // It's not supposed to be reached, ever, but if it is, we'd + // like to be able to tell how we got there. Assemble as + // BL $0 + v = (0 - pc) - 8; + o1 = opbra(ABL, C_SCOND_NONE); + o1 |= (v >> 2) & 0xffffff; + break; } out[0] = o1; diff --git a/src/cmd/5l/optab.c b/src/cmd/5l/optab.c index 76f2d4dda5..be25b6ed61 100644 --- a/src/cmd/5l/optab.c +++ b/src/cmd/5l/optab.c @@ -233,6 +233,8 @@ Optab optab[] = { ASTREXD, C_SOREG,C_REG, C_REG, 92, 4, 0 }, { APLD, C_SOREG,C_NONE, C_NONE, 95, 4, 0 }, + + { AUNDEF, C_NONE, C_NONE, C_NONE, 96, 4, 0 }, { AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0 }, }; diff --git a/src/cmd/5l/pass.c b/src/cmd/5l/pass.c index 34932fd4a0..50593ced97 100644 --- a/src/cmd/5l/pass.c +++ b/src/cmd/5l/pass.c @@ -119,7 +119,7 @@ loop: i--; continue; } - if(a == AB || (a == ARET && q->scond == 14) || a == ARFE) + if(a == AB || (a == ARET && q->scond == 14) || a == ARFE || a == AUNDEF) goto copy; if(q->cond == P || (q->cond->mark&FOLL)) continue; @@ -140,7 +140,7 @@ loop: } (*last)->link = r; *last = r; - if(a == AB || (a == ARET && q->scond == 14) || a == ARFE) + if(a == AB || (a == ARET && q->scond == 14) || a == ARFE || a == AUNDEF) return; r->as = ABNE; if(a == ABNE) @@ -166,7 +166,7 @@ loop: p->mark |= FOLL; (*last)->link = p; *last = p; - if(a == AB || (a == ARET && p->scond == 14) || a == ARFE){ + if(a == AB || (a == ARET && p->scond == 14) || a == ARFE || a == AUNDEF){ return; } if(p->cond != P) diff --git a/src/cmd/5l/span.c b/src/cmd/5l/span.c index 242ba1603d..acacb66bb0 100644 --- a/src/cmd/5l/span.c +++ b/src/cmd/5l/span.c @@ -847,6 +847,7 @@ buildop(void) case ASTREXD: case ATST: case APLD: + case AUNDEF: break; } } diff --git a/src/cmd/6a/lex.c b/src/cmd/6a/lex.c index 23f4637e10..6a1c652654 100644 --- a/src/cmd/6a/lex.c +++ b/src/cmd/6a/lex.c @@ -1007,6 +1007,7 @@ struct "PREFETCHT1", LTYPE2, APREFETCHT1, "PREFETCHT2", LTYPE2, APREFETCHT2, "PREFETCHNTA", LTYPE2, APREFETCHNTA, + "UNDEF", LTYPE0, AUNDEF, 0 }; diff --git a/src/cmd/6l/6.out.h b/src/cmd/6l/6.out.h index 4271944ce4..cd861c038e 100644 --- a/src/cmd/6l/6.out.h +++ b/src/cmd/6l/6.out.h @@ -745,6 +745,8 @@ enum as AMOVQL, ABSWAPL, ABSWAPQ, + + AUNDEF, ALAST }; diff --git a/src/cmd/6l/optab.c b/src/cmd/6l/optab.c index 717d083e99..0716fa4453 100644 --- a/src/cmd/6l/optab.c +++ b/src/cmd/6l/optab.c @@ -1294,6 +1294,8 @@ Optab optab[] = { AMOVQL, yrl_ml, Px, 0x89 }, + { AUNDEF, ynone, Px, 0x0f, 0x0b }, + { AEND }, 0 }; diff --git a/src/cmd/6l/pass.c b/src/cmd/6l/pass.c index 758f61d651..fc89fd8fc3 100644 --- a/src/cmd/6l/pass.c +++ b/src/cmd/6l/pass.c @@ -79,6 +79,7 @@ nofollow(int a) case ARETFL: case ARETFQ: case ARETFW: + case AUNDEF: return 1; } return 0; diff --git a/src/cmd/8a/lex.c b/src/cmd/8a/lex.c index d3a635cdcb..4c3b0e6a32 100644 --- a/src/cmd/8a/lex.c +++ b/src/cmd/8a/lex.c @@ -672,6 +672,7 @@ struct "PREFETCHT1", LTYPE2, APREFETCHT1, "PREFETCHT2", LTYPE2, APREFETCHT2, "PREFETCHNTA", LTYPE2, APREFETCHNTA, + "UNDEF", LTYPE0, AUNDEF, 0 }; diff --git a/src/cmd/8l/8.out.h b/src/cmd/8l/8.out.h index 8329f4a6da..924ba93901 100644 --- a/src/cmd/8l/8.out.h +++ b/src/cmd/8l/8.out.h @@ -458,6 +458,8 @@ enum as APREFETCHNTA, ABSWAPL, + + AUNDEF, ALAST }; diff --git a/src/cmd/8l/optab.c b/src/cmd/8l/optab.c index 81fe25d042..7a588fca49 100644 --- a/src/cmd/8l/optab.c +++ b/src/cmd/8l/optab.c @@ -779,6 +779,8 @@ Optab optab[] = { APREFETCHNTA, yprefetch, Pm, 0x18,(00) }, { ABSWAPL, ybswap, Pm, 0xc8 }, + + { AUNDEF, ynone, Px, 0x0f, 0x0b }, 0 }; diff --git a/src/cmd/8l/pass.c b/src/cmd/8l/pass.c index 9704e3530e..27d8d4ee2a 100644 --- a/src/cmd/8l/pass.c +++ b/src/cmd/8l/pass.c @@ -75,6 +75,7 @@ nofollow(int a) case ARET: case AIRETL: case AIRETW: + case AUNDEF: return 1; } return 0;