about summary refs log tree commit diff stats
Commit message (Collapse)AuthorAgeFilesLines
* 6101Kartik Agaram2020-03-082-45/+92
| | | | | | | | | Make room for additional information for each field in a record/product type. Fields can be used before they're declared, and we may not know the offsets they correspond to at that point. This is going to necessitate a lot of restructuring.
* 6100Kartik Agaram2020-03-081-2/+9
| | | | Fix a bug with a live register being clobbered.
* 6099Kartik Agaram2020-03-081-38/+5
|
* 6098Kartik Agaram2020-03-071-2/+2
| | | | | It was premature to say user-defined record types and array types were done.
* 6097Kartik Agaram2020-03-072-4/+1
| | | | | | I thought I needed to support compute-offset with literal index, but in that case might as well just use an index literal directly. The 'index' instruction with literals already supports non-power-of-2 sizes.
* 6096Kartik Agaram2020-03-072-3/+58
| | | | A new test, and a new bugfix.
* 6095Kartik Agaram2020-03-072-10/+10
|
* 6094 - new 'compute-offset' instructionKartik Agaram2020-03-0715-29/+186
| | | | | | | | | | | | | | | | | | | | | | | If indexing into a type with power-of-2-sized elements we can access them in one instruction: x/reg1: (addr int) <- index A/reg2: (addr array int), idx/reg3: int This translates to a single instruction because x86 instructions support an addressing mode with left-shifts. For non-powers-of-2, however, we need a multiply. To keep things type-safe, it is performed like this: x/reg1: (offset T) <- compute-offset A: (addr array T), idx: int y/reg2: (addr T) <- index A, x An offset is just an int that is guaranteed to be a multiple of size-of(T). Offsets can only be used in index instructions, and the types will eventually be required to line up. In the process, I have to expand Input-size because mu.subx is growing big.
* 6093Kartik Agaram2020-03-072-111/+168
| | | | Some much-needed reorganization.
* 6092Kartik Agaram2020-03-061-10/+10
|
* 6091Kartik Agaram2020-03-0642-5474/+5848
|
* 6090 - new instruction: multiply by immediateKartik Agaram2020-03-065-3/+71
| | | | | | | | | | | | | | | This is a 3-operand instruction: r32 = rm32 * imm32 It looks like https://c9x.me/x86/html/file_module_x86_id_138.html has a bug, implying the same opcode supports a 2-operand version. I don't see that in the Intel manual pdf, or at alternative sites like https://www.felixcloutier.com/x86/imul Native runs seem to validate my understanding. In the process I also fixed a bug in the existing multiply instruction 0f af: the only flags it sets are OF and CF. The other existing multiply instruction f7 was doing things right.
* 6089Kartik Agaram2020-03-0628-70/+70
|
* 6088 - start using setCC instructionsKartik Agaram2020-03-0610-26/+168
|
* 6087Kartik Agaram2020-03-061-7818/+7865
|
* 6086 - `index` into arrays with a literalKartik Agaram2020-03-062-30/+114
|
* 6085Kartik Agaram2020-03-0615-17/+78
| | | | Support parsing ints from strings rather than slices.
* 6084Kartik Agaram2020-03-0621-9166/+9401
|
* 6083Kartik Agaram2020-03-0619-65/+65
|
* 6082 - bugfix in spilling register varsKartik Agaram2020-03-062-3/+263
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In the process I'm starting to realize that my approach to avoiding spills isn't ideal. It works for local variables but not to avoid spilling outputs. To correctly decide whether to spill to an output register or not, we really need to analyze when a variable is live. If we don't do that, we'll end up in one of two bad situations: a) Don't spill the outermost use of an output register (or just the outermost scope in a function). This is weird because it's hard to explain to the programmer why they can overwrite a local with an output above a '{' but not below. b) Disallow overwriting entirely. This is easier to communicate but quite inconvenient. It's nice to be able to use eax for some temporary purpose before overwriting it with the final result of a function. If we instead track liveness, things are convenient and also easier to explain. If a temporary is used after the output has been written that's an obvious problem: "you clobbered the output". (It seems more reasonable to disallow multiple live ranges for the output. Once an output is written it can only be shadowed in a nested block.) That's the bad news. Now for some good news: One lovely property Mu the language has at the moment is that live ranges are guaranteed to be linear segments of code. We don't need to analyze loop-carried dependences. This means that we can decide whether a variable is live purely by scanning later statements for its use. (Defining 'register use' is slightly non-trivial; primitives must somehow specify when they read their output register.) So we don't actually need to worry about a loop reading a register with one type and writing to another type at the end of an iteration. The only way that can happen is if the write at the end was to a local variable, and we're guaranteeing that local variables will be reclaimed at the end of the iteration. So, the sequence of tasks: a) compute register liveness b1) verify that all register variables used at any point in a program are always the topmost use of that register. b2) decide whether to spill/shadow, clobber or flag an error. There's still the open question of where to attach liveness state. It can't be on a var, because liveness varies by use of the var. It can't be on a statement because we may want to know the liveness of variables not referenced in a given statement. Conceptually we want a matrix of locals x stmts (flattened). But I think it's simpler than that. We just want to know liveness at the time of variable declarations. A new register variable can be in one of three states w.r.t. its previous definition: either it's shadowing it, or it can clobber it, or there's a conflict and we need to raise an error. I think we can compute this information for each variable definition by an analysis similar to existing ones, maintaining a stack of variable definitions. The major difference is that we don't pop variables when a block ends. Details to be worked out. But when we do I hope to get these pending tests passing.
* 6081 - ctags for .mu filesKartik Agaram2020-03-056-14/+19
|
* 6080Kartik Agaram2020-03-056-9369/+9711
|
* 6079 - optimize register spillsKartik Agaram2020-03-052-23/+211
| | | | | The second var to the same register in a block doesn't need to spill. We're never going to restore the var it's shadowing.
* 6078 - highlight hex literals in VimKartik Agaram2020-03-023-3/+3
|
* 6077Kartik Agaram2020-03-025-54/+55
|
* 6076Kartik Agaram2020-03-021-20/+21
|
* 6075Kartik Agaram2020-03-021-1/+2
|
* 6074Kartik Agaram2020-02-292-21/+25
|
* 6073Kartik Agaram2020-02-292-11/+28
|
* 6072Kartik Agaram2020-02-292-1/+3
| | | | | | | | | | | | | | I just did an experiment, and test_apps is spending over half its time (95 seconds that could be 40) redundantly clearing every stream before every test. And some of those streams are _large_; the translators for SubX and Mu use streams sizes pessimistically for the largest possible program they can handle (1MB per segment). A single test (the one in assort.subx) spends 24 seconds initializing 2 1MB-segments before processing a dozen lines of text in the blink of an eye. I'm not going to speed this up. But good to know.
* 6071 - array indexing for non-int power-of-2 typesKartik Agaram2020-02-292-11/+163
|
* 6070Kartik Agaram2020-02-2918-103/+99
|
* 6069Kartik Agaram2020-02-293-45/+45
|
* 6068Kartik Agaram2020-02-284-11/+11
|
* 6067Kartik Agaram2020-02-281-0/+58
| | | | Missed the file.
* 6066 - Vim syntax highlighting for Mu filesKartik Agaram2020-02-285-22/+22
|
* 6065Kartik Agaram2020-02-272-3/+3
|
* 6064Kartik Agaram2020-02-2716-3/+3
| | | | Fix CI.
* 6063Kartik Agaram2020-02-271-8816/+8893
|
* 6062Kartik Agaram2020-02-272-10/+92
|
* 6061Kartik Agaram2020-02-273-44/+44
|
* 6060Kartik Agaram2020-02-271-11/+11
|
* 6059Kartik Agaram2020-02-272-0/+13
|
* 6058Kartik Agaram2020-02-271-15/+15
|
* 6057Kartik Agaram2020-02-271-4/+6
|
* 6056Kartik Agaram2020-02-272-8506/+9028
|
* 6055 - record types and the 'get' instructionKartik Agaram2020-02-272-6/+487
| | | | | | | | | | | This is a lot of code for a single test, and it took a long time to get my data model just right. But the test coverage seems ok because it feels mostly like straight-line code. We'll see. I've also had to add a lot of prints. We really need app-level trace generation pretty urgently. That requires deciding how to turn it on/off from the commandline. And I've been reluctant to start relying on the hairy interface that is POSIX open().
* 6054Kartik Agaram2020-02-242-3/+21
|
* 6053Kartik Agaram2020-02-233-3/+3
|
* 6052Kartik Agaram2020-02-231-10/+21
|