As: int16(op),
}
switch {
+ case target.Type == obj.TYPE_BRANCH:
+ // JMP 4(PC)
+ prog.To = obj.Addr{
+ Type: obj.TYPE_BRANCH,
+ Offset: p.pc + 1 + target.Offset, // +1 because p.pc is incremented in link, below.
+ }
case target.Type == obj.TYPE_REG:
// JMP R1
prog.To = *target
}
case target.Type == obj.TYPE_MEM && target.Name == obj.NAME_NONE:
// JMP 4(PC)
- if target.Reg == arch.RPC {
- prog.To = obj.Addr{
- Type: obj.TYPE_BRANCH,
- Offset: p.pc + 1 + target.Offset, // +1 because p.pc is incremented in link, below.
- }
- } else {
- prog.To = *target
- }
+ prog.To = *target
default:
p.errorf("cannot assemble jump %+v", target)
}
t.Errorf("fail at %s: got %s; expected %s\n", test.input, result, test.output)
}
}
+
+ // Special case for AX:DX, which is really two operands so isn't print correcctly
+ // by Aconv, but is OK by the -S output.
+ parser.start(lex.Tokenize("AX:BX)"))
+ addr := obj.Addr{}
+ parser.operand(&addr)
+ want := obj.Addr{
+ Type: obj.TYPE_REG,
+ Reg: int16(architecture.Registers["AX"]),
+ Class: int8(architecture.Registers["BX"]),
+ }
+ if want != addr {
+ t.Errorf("AX:DX: expected %+v got %+v", want, addr)
+ }
+
}
type operandTest struct {
{"(SP)", "(SP)"},
{"(6+8)(AX)", "14(AX)"},
{"(8*4)(BP)", "32(BP)"},
- // {"+3(PC)", "+3(PC)"}, TODO: Need to parse this knowing it's a branch.
+ {"+3(PC)", "3(PC)"},
+ {"-3(PC)", "-3(PC)"},
{"-1(DI)(BX*1)", "-1(DI)(BX*1)"},
{"-64(SI)(BX*1)", "-64(SI)(BX*1)"},
{"-96(SI)(BX*1)", "-96(SI)(BX*1)"},
{"AL", "AL"},
{"AX", "AX"},
- // {"AX:DX", "AX:DX"}, TODO: prints as AX although -S output is correct.
+ // {"AX:DX", "AX:DX"}, Handled in TestAMD64OperandParser directly.
{"BP", "BP"},
{"BX", "BX"},
{"CX", "CX"},
continue
}
if tok == ':' {
- // LABELS
+ // Labels.
p.pendingLabels = append(p.pendingLabels, word)
return true
}
case "FP":
addr.Name = obj.NAME_PARAM
case "PC":
- // Fine as is.
if prefix != 0 {
p.errorf("illegal addressing mode for PC")
}
- addr.Reg = arch.RPC // Tells asmJump how to interpret this address.
+ addr.Type = obj.TYPE_BRANCH // We set the type and leave NAME untouched. See asmJump.
case "SB":
addr.Name = obj.NAME_EXTERN
if isStatic {