test(asm): pin the flag-list TEXT shapes against the toolchain
Assisted-by: GLM 5.3 Flash
This commit is contained in:
1 parent
9179d5cc7a
commit
6f3e054bab
4 files changed
+145
-10
No files matched your search
+12
-7
@@ -77,7 +77,8 @@ func flagsRun(g []token.Token) []token.Token {
|
||||
// evalFlags evaluates one flags operand. Every identifier must name a
|
||||
// flag in textFlags; the toolchain rejects any other with "unexpected NAME
|
||||
// evaluating expression", and so does this. The whole operand folds to
|
||||
// one integer, which is returned as the value.
|
||||
// one integer, which is returned as the value. pseudo names the directive
|
||||
// in the toolchain's own diagnostics ("TEXT", "GLOBL").
|
||||
//
|
||||
// The names returned follow the operand's own spelling: an operand written
|
||||
// purely as names keeps them in written order, duplicates included, the
|
||||
@@ -89,17 +90,21 @@ func flagsRun(g []token.Token) []token.Token {
|
||||
// After a failure the names collected so far are returned with value 0:
|
||||
// the tree stays usable beside the diagnostic, and value 0 is exactly the
|
||||
// flags the assembler can trust the operand for.
|
||||
func (p *state) evalFlags(g []token.Token, keepWritten bool) ([]string, int64) {
|
||||
func (p *state) evalFlags(g []token.Token, keepWritten bool, pseudo string) ([]string, int64) {
|
||||
if len(g) == 0 {
|
||||
return nil, 0
|
||||
}
|
||||
// An explicit '$' makes the operand an immediate ('$NOSPLIT' over the
|
||||
// preprocessor's '$4'); the toolchain reads it as the same constant.
|
||||
// The flags operand is a bare constant expression; the immediate
|
||||
// spelling is the toolchain's "TEXT: expected integer constant".
|
||||
if g[0].Kind == token.Dollar {
|
||||
g = g[1:]
|
||||
if len(g) == 0 {
|
||||
return nil, 0
|
||||
if p.expand {
|
||||
found := "$"
|
||||
if len(g) > 1 {
|
||||
found += g[1].Text
|
||||
}
|
||||
p.errorf(g[0].Pos, "%s: expected integer constant; found %s", pseudo, found)
|
||||
}
|
||||
return nil, 0
|
||||
}
|
||||
|
||||
sub := make([]token.Token, 0, len(g))
|
||||
|
||||
@@ -53,7 +53,10 @@ func TestTextFlagsExpression(t *testing.T) {
|
||||
{"(NOSPLIT|NOFRAME)", []string{"NOSPLIT", "NOFRAME"}, 516},
|
||||
{"NOSPLIT|4", []string{"NOSPLIT"}, 4},
|
||||
{"NOSPLIT&DUPOK", nil, 0},
|
||||
{"$NOSPLIT", []string{"NOSPLIT"}, 4},
|
||||
// The immediate spelling is the toolchain's "expected integer
|
||||
// constant" on the assembly path; the raw view reads nothing from
|
||||
// it and stays quiet.
|
||||
{"$NOSPLIT", nil, 0},
|
||||
} {
|
||||
txt := parseTextHeader(t, "TEXT \u00b7f(SB), "+c.operand+", $0")
|
||||
if !slices.Equal(txt.Flags, c.wantFlag) {
|
||||
|
||||
+2
-2
@@ -261,7 +261,7 @@ func (p *state) parseText(line []token.Token) {
|
||||
var frame []token.Token
|
||||
switch {
|
||||
case len(ops) >= 2:
|
||||
text.Flags, text.FlagVal = p.evalFlags(flagsRun(ops[0]), false)
|
||||
text.Flags, text.FlagVal = p.evalFlags(flagsRun(ops[0]), false, "TEXT")
|
||||
frame = ops[1]
|
||||
if len(ops) > 2 {
|
||||
p.errorf(line[0].Pos, "expect two or three operands for TEXT")
|
||||
@@ -355,7 +355,7 @@ func (p *state) parseGlobl(line []token.Token) *ast.Globl {
|
||||
ops := splitOperands(rest)
|
||||
switch {
|
||||
case len(ops) >= 2:
|
||||
g.Flags, g.FlagVal = p.evalFlags(flagsRun(ops[0]), true)
|
||||
g.Flags, g.FlagVal = p.evalFlags(flagsRun(ops[0]), true, "GLOBL")
|
||||
g.Size = parseOperand(ops[1], false)
|
||||
case len(ops) == 1:
|
||||
g.Size = parseOperand(ops[0], false)
|
||||
|
||||
Reference in new issue
Block a user