diff --git a/include/avian/vm/codegen/registers.h b/include/avian/vm/codegen/registers.h index 317bb2215a..32b005d61a 100644 --- a/include/avian/vm/codegen/registers.h +++ b/include/avian/vm/codegen/registers.h @@ -45,6 +45,28 @@ public: { } }; +class RegisterIterator { +public: + int index; + const RegisterMask& mask; + + inline RegisterIterator(const RegisterMask& mask): + index(mask.start), + mask(mask) {} + + inline bool hasNext() { + return index < mask.limit; + } + + inline int next() { + int r = index; + do { + index++; + } while(index < mask.limit && !(mask.mask & (1 << index))); + return r; + } +}; + } // namespace codegen } // namespace avian diff --git a/src/tools/audit-codegen/main.cpp b/src/tools/audit-codegen/main.cpp index 77f0b36e8a..d201cd43a4 100644 --- a/src/tools/audit-codegen/main.cpp +++ b/src/tools/audit-codegen/main.cpp @@ -8,23 +8,80 @@ There is NO WARRANTY for this software. See license.txt for details. */ -#include "system.h" +#include #include -#include "codegen/lir.h" -#include "codegen/assembler.h" -#include "codegen/targets.h" +#include +#include +#include +#include + +#include // since we aren't linking against libstdc++, we must implement this // ourselves: extern "C" void __cxa_pure_virtual(void) { abort(); } +using namespace vm; using namespace avian::codegen; using namespace avian::util; -void generateCode(Assembler::Architecture* arch) { - for() +class BasicEnv { +public: + System* s; + Heap* heap; + Assembler::Architecture* arch; + + BasicEnv(): + s(makeSystem(0)), + heap(makeHeap(s, 32 * 1024)), + arch(makeArchitectureNative(s, true)) + { + arch->acquire(); + } + + ~BasicEnv() { + arch->release(); + s->dispose(); + } +}; + +class Asm { +public: + Zone zone; + Assembler* a; + + Asm(BasicEnv& env): + zone(env.s, env.heap, 8192), + a(env.arch->makeAssembler(env.heap, &zone)) + { } + + ~Asm() { + a->dispose(); + } +}; + +void generateCode(BasicEnv& env) { + Asm a(env); + for(RegisterIterator it(env.arch->registerFile()->generalRegisters); it.hasNext(); ) { + int r = it.next(); + lir::Register reg(r); + a.a->apply(lir::Add, + OperandInfo(4, lir::RegisterOperand, ®), + OperandInfo(4, lir::RegisterOperand, ®), + OperandInfo(4, lir::RegisterOperand, ®)); + } + unsigned length = a.a->endBlock(false)->resolve(0, 0); + printf("length: %d\n", length); + uint8_t* data = static_cast(env.s->tryAllocate(length)); + a.a->setDestination(data); + a.a->write(); + for(unsigned i = 0; i < length; i++) { + printf("%02x ", data[i]); + } + printf("\n"); + env.s->free(data); } class Arguments { @@ -51,13 +108,9 @@ public: int main(int argc, char** argv) { Arguments args(argc, argv); - vm::System* s = vm::makeSystem(0); - Assembler::Architecture* arch = makeArchitectureNative(s, true); - arch->acquire(); + BasicEnv env; - generateCode(arch); + generateCode(env); - arch->release(); - s->dispose(); return 0; } \ No newline at end of file diff --git a/unittest/codegen/registers-test.cpp b/unittest/codegen/registers-test.cpp new file mode 100644 index 0000000000..946e45ebab --- /dev/null +++ b/unittest/codegen/registers-test.cpp @@ -0,0 +1,44 @@ +/* Copyright (c) 2008-2011, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +#include + +#include + +#include "test-harness.h" + + +using namespace avian::codegen; +using namespace vm; + + +class RegisterIteratorTest : public Test { +public: + RegisterIteratorTest(): + Test("RegisterIterator") + {} + + virtual void run() { + RegisterMask regs(0x55); + assertEqual(0, regs.start); + assertEqual(7, regs.limit); + + RegisterIterator it(regs); + assertTrue(it.hasNext()); + assertEqual(0, it.next()); + assertTrue(it.hasNext()); + assertEqual(2, it.next()); + assertTrue(it.hasNext()); + assertEqual(4, it.next()); + assertTrue(it.hasNext()); + assertEqual(6, it.next()); + assertFalse(it.hasNext()); + } +} registerIteratorTest;