c65gm/internal/optimizer/config.go

72 lines
2 KiB
Go

package optimizer
import (
"strconv"
"strings"
"c65gm/internal/preproc"
)
type Config struct {
EnableLoad bool
EnableImm bool
EnableJmp bool
EnableSelf bool
EnableStoreLoad bool
Debug bool
ShowMarkers bool
IOMap [65536]bool
}
func NewConfig(ps preproc.PragmaSet) *Config {
all := ps.GetPragma("_P_OPT_ALL") != "" && ps.GetPragma("_P_OPT_ALL") != "0"
return &Config{
EnableLoad: all || (ps.GetPragma("_P_OPT_LOAD") != "" && ps.GetPragma("_P_OPT_LOAD") != "0"),
EnableImm: all || (ps.GetPragma("_P_OPT_IMM") != "" && ps.GetPragma("_P_OPT_IMM") != "0"),
EnableJmp: all || (ps.GetPragma("_P_OPT_JMP") != "" && ps.GetPragma("_P_OPT_JMP") != "0"),
EnableSelf: all || (ps.GetPragma("_P_OPT_SELF") != "" && ps.GetPragma("_P_OPT_SELF") != "0"),
EnableStoreLoad: all || (ps.GetPragma("_P_OPT_STLD") != "" && ps.GetPragma("_P_OPT_STLD") != "0"),
Debug: (ps.GetPragma("_P_OPT_DEBUG") != "" && ps.GetPragma("_P_OPT_DEBUG") != "0"),
ShowMarkers: (ps.GetPragma("_P_OPT_MARKERS") != "" && ps.GetPragma("_P_OPT_MARKERS") != "0"),
}
}
func (c *Config) Any() bool {
return c.EnableLoad || c.EnableImm || c.EnableJmp || c.EnableSelf || c.EnableStoreLoad
}
// BuildIOMap scans all pragma sets for _P_OPT_IO and marks I/O regions.
func (c *Config) BuildIOMap(pragma *preproc.Pragma) {
for i := 0; i <= pragma.GetCurrentPragmaSetIndex(); i++ {
val := pragma.GetPragmaSetByIndex(i).GetPragma("_P_OPT_IO")
if val == "" {
continue
}
parts := strings.Fields(val)
if len(parts) >= 2 {
start := parsePragmaAddr(parts[0])
end := parsePragmaAddr(parts[1])
if start >= 0 && end >= 0 && start <= end && start < 65536 {
for a := start; a <= end && a < 65536; a++ {
c.IOMap[a] = true
}
}
}
}
}
func parsePragmaAddr(s string) int {
if strings.HasPrefix(s, "$") {
v, err := strconv.ParseUint(s[1:], 16, 16)
if err != nil {
return -1
}
return int(v)
}
v, err := strconv.ParseUint(s, 10, 16)
if err != nil {
return -1
}
return int(v)
}