summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDerek Hower <drh5@cs.wisc.edu>2010-01-19 15:48:12 -0600
committerDerek Hower <drh5@cs.wisc.edu>2010-01-19 15:48:12 -0600
commit279f179babc9e5663156777c533c06edc91bce9a (patch)
treee6718ee514cc81678491b50562ce8c463c0b20fd /src
parent5aa104e072eb20f6aca49b169521b0c2da33c844 (diff)
parent295516a590b6e47c9a881f193027447e500c749c (diff)
downloadgem5-279f179babc9e5663156777c533c06edc91bce9a.tar.xz
merge
Diffstat (limited to 'src')
-rw-r--r--src/SConscript100
-rw-r--r--src/arch/alpha/faults.cc2
-rw-r--r--src/arch/alpha/isa.cc4
-rw-r--r--src/arch/alpha/isa.hh5
-rw-r--r--src/arch/alpha/isa/decoder.isa2
-rw-r--r--src/arch/alpha/isa/mem.isa2
-rw-r--r--src/arch/alpha/linux/linux.hh16
-rw-r--r--src/arch/alpha/linux/process.cc17
-rw-r--r--src/arch/alpha/process.cc4
-rw-r--r--src/arch/alpha/process.hh2
-rw-r--r--src/arch/alpha/tru64/process.cc41
-rw-r--r--src/arch/alpha/tru64/tru64.hh1
-rw-r--r--src/arch/arm/ArmInterrupts.py33
-rw-r--r--src/arch/arm/ArmSystem.py (renamed from src/python/m5/environment.py)20
-rw-r--r--src/arch/arm/SConscript13
-rw-r--r--src/arch/arm/faults.cc534
-rw-r--r--src/arch/arm/faults.hh557
-rw-r--r--src/arch/arm/insts/macromem.hh25
-rw-r--r--src/arch/arm/insts/static_inst.cc10
-rw-r--r--src/arch/arm/insts/static_inst.hh50
-rw-r--r--src/arch/arm/interrupts.cc (renamed from src/mem/slicc/ast/AST.cc)20
-rw-r--r--src/arch/arm/interrupts.hh (renamed from src/mem/slicc/ast/LiteralExprAST.hh)126
-rw-r--r--src/arch/arm/intregs.hh337
-rw-r--r--src/arch/arm/isa.hh116
-rw-r--r--src/arch/arm/isa/bitfields.isa4
-rw-r--r--src/arch/arm/isa/decoder.isa362
-rw-r--r--src/arch/arm/isa/formats/branch.isa4
-rw-r--r--src/arch/arm/isa/formats/fp.isa4
-rw-r--r--src/arch/arm/isa/formats/macromem.isa126
-rw-r--r--src/arch/arm/isa/formats/pred.isa90
-rw-r--r--src/arch/arm/isa/formats/unimp.isa2
-rw-r--r--src/arch/arm/isa/formats/unknown.isa2
-rw-r--r--src/arch/arm/isa/formats/util.isa6
-rw-r--r--src/arch/arm/isa/operands.isa24
-rw-r--r--src/arch/arm/isa_traits.hh2
-rw-r--r--src/arch/arm/kernel_stats.hh (renamed from src/mem/slicc/ast/TypeAST.cc)56
-rw-r--r--src/arch/arm/linux/linux.hh16
-rw-r--r--src/arch/arm/linux/process.cc12
-rw-r--r--src/arch/arm/linux/process.hh2
-rw-r--r--src/arch/arm/miscregs.hh42
-rw-r--r--src/arch/arm/nativetrace.cc3
-rw-r--r--src/arch/arm/process.cc4
-rw-r--r--src/arch/arm/process.hh2
-rw-r--r--src/arch/arm/registers.hh45
-rw-r--r--src/arch/arm/stacktrace.cc151
-rw-r--r--src/arch/arm/stacktrace.hh16
-rw-r--r--src/arch/arm/system.cc (renamed from src/mem/slicc/ast/TypeFieldAST.cc)33
-rw-r--r--src/arch/arm/system.hh (renamed from src/mem/slicc/ast/StatementAST.cc)50
-rw-r--r--src/arch/arm/tlb.cc10
-rw-r--r--src/arch/arm/types.hh5
-rw-r--r--src/arch/arm/utility.cc (renamed from src/mem/slicc/ast/ExprStatementAST.cc)67
-rw-r--r--src/arch/arm/utility.hh14
-rwxr-xr-xsrc/arch/isa_parser.py1396
-rw-r--r--src/arch/micro_asm.py4
-rwxr-xr-xsrc/arch/mips/BISystem.py5
-rw-r--r--src/arch/mips/MipsCPU.py5
-rw-r--r--src/arch/mips/MipsSystem.py6
-rwxr-xr-xsrc/arch/mips/dsp.cc4
-rw-r--r--src/arch/mips/isa.hh7
-rw-r--r--src/arch/mips/isa/formats/mem.isa2
-rw-r--r--src/arch/mips/linux/linux.hh17
-rw-r--r--src/arch/mips/linux/process.cc27
-rw-r--r--src/arch/mips/linux/process.hh2
-rw-r--r--src/arch/mips/process.cc85
-rw-r--r--src/arch/mips/process.hh6
-rw-r--r--src/arch/power/PowerTLB.py37
-rw-r--r--src/arch/power/SConscript61
-rw-r--r--src/arch/power/SConsopts33
-rw-r--r--src/arch/power/faults.hh (renamed from src/mem/slicc/symbols/Symbol.cc)85
-rw-r--r--src/arch/power/insts/branch.cc169
-rw-r--r--src/arch/power/insts/branch.hh241
-rw-r--r--src/arch/power/insts/condition.cc (renamed from src/mem/slicc/symbols/Var.cc)48
-rw-r--r--src/arch/power/insts/condition.hh (renamed from src/mem/slicc/ast/DeclAST.hh)93
-rw-r--r--src/arch/power/insts/floating.cc60
-rw-r--r--src/arch/power/insts/floating.hh153
-rw-r--r--src/arch/power/insts/integer.cc170
-rw-r--r--src/arch/power/insts/integer.hh176
-rw-r--r--src/arch/power/insts/mem.cc (renamed from src/mem/slicc/ast/DeclListAST.cc)84
-rw-r--r--src/arch/power/insts/mem.hh (renamed from src/mem/slicc/ast/TypeDeclAST.cc)99
-rw-r--r--src/arch/power/insts/misc.cc60
-rw-r--r--src/arch/power/insts/misc.hh (renamed from src/mem/slicc/ast/LiteralExprAST.cc)52
-rw-r--r--src/arch/power/insts/static_inst.cc62
-rw-r--r--src/arch/power/insts/static_inst.hh (renamed from src/mem/slicc/ast/PairListAST.hh)76
-rw-r--r--src/arch/power/isa.hh115
-rw-r--r--src/arch/power/isa/bitfields.isa84
-rw-r--r--src/arch/power/isa/decoder.isa593
-rw-r--r--src/arch/power/isa/formats/basic.isa103
-rw-r--r--src/arch/power/isa/formats/branch.isa222
-rw-r--r--src/arch/power/isa/formats/condition.isa47
-rw-r--r--src/arch/power/isa/formats/formats.isa60
-rw-r--r--src/arch/power/isa/formats/fp.isa132
-rw-r--r--src/arch/power/isa/formats/integer.isa369
-rw-r--r--src/arch/power/isa/formats/mem.isa351
-rw-r--r--src/arch/power/isa/formats/misc.isa61
-rw-r--r--src/arch/power/isa/formats/unimp.isa146
-rw-r--r--src/arch/power/isa/formats/unknown.isa87
-rw-r--r--src/arch/power/isa/formats/util.isa174
-rw-r--r--src/arch/power/isa/includes.isa92
-rw-r--r--src/arch/power/isa/main.isa57
-rw-r--r--src/arch/power/isa/operands.isa81
-rw-r--r--src/arch/power/isa_traits.hh (renamed from src/arch/isa_specific.hh)77
-rw-r--r--src/arch/power/linux/linux.cc79
-rw-r--r--src/arch/power/linux/linux.hh148
-rw-r--r--src/arch/power/linux/process.cc456
-rw-r--r--src/arch/power/linux/process.hh (renamed from src/mem/slicc/generator/fileio.cc)58
-rw-r--r--src/arch/power/locked_mem.hh (renamed from src/mem/slicc/ast/PairAST.cc)56
-rw-r--r--src/arch/power/microcode_rom.hh (renamed from src/mem/slicc/ast/PairListAST.cc)32
-rw-r--r--src/arch/power/miscregs.hh (renamed from src/mem/slicc/ast/CheckAllocateStatementAST.hh)103
-rw-r--r--src/arch/power/mmaped_ipr.hh66
-rw-r--r--src/arch/power/pagetable.cc (renamed from src/mem/slicc/ast/EnumExprAST.cc)84
-rw-r--r--src/arch/power/pagetable.hh158
-rw-r--r--src/arch/power/predecoder.hh121
-rw-r--r--src/arch/power/process.cc288
-rw-r--r--src/arch/power/process.hh59
-rw-r--r--src/arch/power/registers.hh105
-rw-r--r--src/arch/power/remote_gdb.hh (renamed from src/mem/slicc/ast/TypeAST.hh)91
-rw-r--r--src/arch/power/stacktrace.hh148
-rw-r--r--src/arch/power/tlb.cc322
-rw-r--r--src/arch/power/tlb.hh171
-rw-r--r--src/arch/power/types.hh (renamed from src/mem/slicc/ast/ExprAST.hh)93
-rw-r--r--src/arch/power/utility.hh118
-rw-r--r--src/arch/power/vtophys.hh57
-rw-r--r--src/arch/sparc/isa/decoder.isa3
-rw-r--r--src/arch/sparc/linux/linux.hh32
-rw-r--r--src/arch/sparc/linux/syscalls.cc14
-rw-r--r--src/arch/sparc/process.cc8
-rw-r--r--src/arch/sparc/process.hh4
-rw-r--r--src/arch/sparc/solaris/process.cc3
-rw-r--r--src/arch/x86/X86TLB.py9
-rw-r--r--src/arch/x86/interrupts.cc2
-rw-r--r--src/arch/x86/isa.cc2
-rw-r--r--src/arch/x86/isa/decoder/two_byte_opcodes.isa18
-rw-r--r--src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py2
-rw-r--r--src/arch/x86/isa/insts/general_purpose/data_transfer/move.py30
-rw-r--r--src/arch/x86/isa/insts/simd128/floating_point/arithmetic/horizontal_addition.py22
-rw-r--r--src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py18
-rw-r--r--src/arch/x86/isa/insts/simd128/integer/data_transfer/move.py56
-rw-r--r--src/arch/x86/isa/insts/simd128/integer/shift/left_logical_shift.py40
-rw-r--r--src/arch/x86/isa/insts/simd128/integer/shift/right_logical_shift.py38
-rw-r--r--src/arch/x86/isa/insts/system/segmentation.py9
-rw-r--r--src/arch/x86/isa/microops/ldstop.isa4
-rw-r--r--src/arch/x86/isa/microops/mediaop.isa33
-rw-r--r--src/arch/x86/isa/microops/regop.isa26
-rw-r--r--src/arch/x86/linux/linux.hh37
-rw-r--r--src/arch/x86/linux/syscalls.cc65
-rw-r--r--src/arch/x86/predecoder_tables.cc2
-rw-r--r--src/arch/x86/process.cc47
-rw-r--r--src/arch/x86/process.hh15
-rw-r--r--src/arch/x86/system.cc2
-rw-r--r--src/arch/x86/tlb.cc20
-rw-r--r--src/base/bigint.cc4
-rw-r--r--src/base/bigint.hh5
-rw-r--r--src/base/cp_annotate.cc1
-rw-r--r--src/base/cp_annotate.hh1
-rw-r--r--src/base/inet.cc1
-rw-r--r--src/base/loader/elf_object.cc13
-rw-r--r--src/base/loader/object_file.hh3
-rw-r--r--src/base/remote_gdb.cc3
-rw-r--r--src/base/types.hh1
-rw-r--r--src/cpu/BaseCPU.py69
-rw-r--r--src/cpu/CheckerCPU.py1
-rw-r--r--src/cpu/SConscript5
-rw-r--r--src/cpu/base.cc2
-rw-r--r--src/cpu/base.hh1
-rw-r--r--src/cpu/base_dyn_inst.hh1
-rw-r--r--src/cpu/base_dyn_inst_impl.hh7
-rw-r--r--src/cpu/checker/cpu.cc2
-rw-r--r--src/cpu/checker/cpu_impl.hh1
-rw-r--r--src/cpu/checker/thread_context.hh1
-rw-r--r--src/cpu/exetrace.cc1
-rw-r--r--src/cpu/inorder/InOrderCPU.py1
-rw-r--r--src/cpu/inorder/SConscript1
-rw-r--r--src/cpu/inorder/cpu.cc132
-rw-r--r--src/cpu/inorder/cpu.hh42
-rw-r--r--src/cpu/inorder/inorder_cpu_builder.cc5
-rw-r--r--src/cpu/inorder/inorder_dyn_inst.cc37
-rw-r--r--src/cpu/inorder/inorder_dyn_inst.hh30
-rw-r--r--src/cpu/inorder/inorder_trace.cc1
-rw-r--r--src/cpu/inorder/pipeline_stage.cc1
-rw-r--r--src/cpu/inorder/reg_dep_map.cc1
-rw-r--r--src/cpu/inorder/reg_dep_map.hh1
-rw-r--r--src/cpu/inorder/resource.hh1
-rw-r--r--src/cpu/inorder/resources/bpred_unit.cc1
-rw-r--r--src/cpu/inorder/resources/branch_predictor.cc1
-rw-r--r--src/cpu/inorder/resources/cache_unit.cc2
-rw-r--r--src/cpu/inorder/resources/cache_unit.hh10
-rw-r--r--src/cpu/inorder/resources/decode_unit.cc1
-rw-r--r--src/cpu/inorder/resources/fetch_seq_unit.cc1
-rw-r--r--src/cpu/inorder/resources/fetch_seq_unit.hh1
-rw-r--r--src/cpu/inorder/resources/inst_buffer.cc2
-rw-r--r--src/cpu/inorder/resources/inst_buffer_new.cc2
-rw-r--r--src/cpu/inorder/resources/mult_div_unit.cc34
-rw-r--r--src/cpu/inorder/resources/mult_div_unit.hh2
-rw-r--r--src/cpu/inorder/resources/tlb_unit.cc2
-rw-r--r--src/cpu/inorder/resources/tlb_unit.hh1
-rw-r--r--src/cpu/inorder/resources/use_def.cc2
-rw-r--r--src/cpu/inorder/thread_context.cc70
-rw-r--r--src/cpu/inorder/thread_context.hh41
-rw-r--r--src/cpu/inorder/thread_state.cc (renamed from src/mem/slicc/generator/fileio.hh)31
-rw-r--r--src/cpu/inorder/thread_state.hh30
-rw-r--r--src/cpu/inst_seq.hh2
-rw-r--r--src/cpu/inteltrace.cc1
-rw-r--r--src/cpu/legiontrace.cc6
-rw-r--r--src/cpu/memtest/MemTest.py1
-rw-r--r--src/cpu/o3/O3CPU.py8
-rw-r--r--src/cpu/o3/O3Checker.py1
-rw-r--r--src/cpu/o3/bpred_unit_impl.hh6
-rw-r--r--src/cpu/o3/commit_impl.hh9
-rw-r--r--src/cpu/o3/cpu.cc3
-rw-r--r--src/cpu/o3/cpu.hh4
-rw-r--r--src/cpu/o3/decode_impl.hh1
-rw-r--r--src/cpu/o3/dyn_inst.hh1
-rw-r--r--src/cpu/o3/fetch.hh1
-rw-r--r--src/cpu/o3/fetch_impl.hh3
-rw-r--r--src/cpu/o3/free_list.hh1
-rw-r--r--src/cpu/o3/iew_impl.hh1
-rw-r--r--src/cpu/o3/impl.hh2
-rw-r--r--src/cpu/o3/lsq_unit.hh1
-rw-r--r--src/cpu/o3/lsq_unit_impl.hh2
-rw-r--r--src/cpu/o3/regfile.hh5
-rw-r--r--src/cpu/o3/rename.hh1
-rw-r--r--src/cpu/o3/rename_impl.hh1
-rw-r--r--src/cpu/o3/rename_map.hh3
-rw-r--r--src/cpu/o3/rob.hh2
-rw-r--r--src/cpu/o3/scoreboard.cc2
-rwxr-xr-xsrc/cpu/o3/thread_context.hh4
-rwxr-xr-xsrc/cpu/o3/thread_context_impl.hh1
-rw-r--r--src/cpu/ozone/OzoneCPU.py6
-rw-r--r--src/cpu/ozone/OzoneChecker.py1
-rw-r--r--src/cpu/ozone/SimpleOzoneCPU.py4
-rw-r--r--src/cpu/ozone/cpu.hh1
-rw-r--r--src/cpu/ozone/cpu_impl.hh1
-rw-r--r--src/cpu/ozone/dyn_inst.hh1
-rw-r--r--src/cpu/ozone/dyn_inst_impl.hh1
-rw-r--r--src/cpu/ozone/front_end.hh1
-rw-r--r--src/cpu/ozone/front_end_impl.hh4
-rw-r--r--src/cpu/ozone/inorder_back_end_impl.hh1
-rw-r--r--src/cpu/ozone/lsq_unit.hh1
-rw-r--r--src/cpu/ozone/lsq_unit_impl.hh1
-rw-r--r--src/cpu/ozone/lw_back_end_impl.hh2
-rw-r--r--src/cpu/ozone/lw_lsq.hh1
-rw-r--r--src/cpu/ozone/lw_lsq_impl.hh4
-rw-r--r--src/cpu/ozone/rename_table.hh1
-rw-r--r--src/cpu/ozone/rename_table_impl.hh2
-rw-r--r--src/cpu/ozone/simple_params.hh1
-rw-r--r--src/cpu/ozone/thread_state.hh5
-rw-r--r--src/cpu/profile.hh1
-rw-r--r--src/cpu/simple/AtomicSimpleCPU.py1
-rw-r--r--src/cpu/simple/TimingSimpleCPU.py1
-rw-r--r--src/cpu/simple/atomic.cc20
-rw-r--r--src/cpu/simple/base.cc1
-rw-r--r--src/cpu/simple/base.hh1
-rw-r--r--src/cpu/simple/timing.cc9
-rw-r--r--src/cpu/simple_thread.cc11
-rw-r--r--src/cpu/simple_thread.hh1
-rw-r--r--src/cpu/static_inst.hh1
-rw-r--r--src/cpu/thread_context.cc1
-rw-r--r--src/cpu/thread_context.hh1
-rw-r--r--src/cpu/thread_state.hh1
-rw-r--r--src/dev/Uart.py1
-rw-r--r--src/dev/alpha/tsunami.cc1
-rw-r--r--src/dev/alpha/tsunami_cchip.cc1
-rw-r--r--src/dev/alpha/tsunami_io.cc1
-rw-r--r--src/dev/alpha/tsunami_pchip.cc1
-rw-r--r--src/dev/arm/SConscript36
-rw-r--r--src/dev/arm/Versatile.py51
-rw-r--r--src/dev/arm/versatile.cc122
-rw-r--r--src/dev/arm/versatile.hh108
-rw-r--r--src/dev/baddev.cc1
-rw-r--r--src/dev/ide_ctrl.cc2
-rw-r--r--src/dev/ide_disk.cc1
-rw-r--r--src/dev/mc146818.cc24
-rwxr-xr-xsrc/dev/mips/malta.cc2
-rwxr-xr-xsrc/dev/mips/malta_cchip.cc3
-rwxr-xr-xsrc/dev/mips/malta_io.cc1
-rwxr-xr-xsrc/dev/mips/malta_pchip.cc1
-rw-r--r--src/dev/ns_gige.cc1
-rw-r--r--src/dev/platform.cc1
-rw-r--r--src/dev/sinic.cc1
-rw-r--r--src/dev/sparc/dtod.cc1
-rw-r--r--src/dev/sparc/iob.cc14
-rw-r--r--src/dev/sparc/t1000.cc1
-rw-r--r--src/dev/uart8250.cc1
-rw-r--r--src/dev/x86/i82094aa.cc2
-rw-r--r--src/dev/x86/pc.cc1
-rw-r--r--src/kern/linux/linux.cc1
-rw-r--r--src/kern/linux/linux.hh12
-rw-r--r--src/kern/linux/printk.hh2
-rw-r--r--src/kern/operatingsystem.hh4
-rw-r--r--src/kern/system_events.cc2
-rw-r--r--src/kern/tru64/dump_mbuf.cc1
-rw-r--r--src/kern/tru64/tru64.hh79
-rw-r--r--src/kern/tru64/tru64_events.cc1
-rw-r--r--src/mem/Bus.py4
-rw-r--r--src/mem/RubyMemory.py5
-rw-r--r--src/mem/SConscript1
-rw-r--r--src/mem/bridge.cc4
-rw-r--r--src/mem/bus.cc3
-rw-r--r--src/mem/cache/BaseCache.py2
-rw-r--r--src/mem/cache/base.hh2
-rw-r--r--src/mem/cache/builder.cc3
-rw-r--r--src/mem/cache/cache_impl.hh19
-rw-r--r--src/mem/cache/prefetch/base.cc20
-rw-r--r--src/mem/cache/prefetch/base.hh4
-rw-r--r--src/mem/packet.hh2
-rw-r--r--src/mem/packet_access.hh1
-rw-r--r--src/mem/page_table.cc1
-rw-r--r--src/mem/page_table.hh1
-rw-r--r--src/mem/physical.cc2
-rw-r--r--src/mem/port_impl.hh3
-rw-r--r--src/mem/protocol/MI_example-dir.sm24
-rw-r--r--src/mem/protocol/MI_example-dma.sm6
-rw-r--r--src/mem/protocol/MI_example-msg.sm1
-rw-r--r--src/mem/protocol/MOESI_CMP_token-L1cache.sm353
-rw-r--r--src/mem/protocol/MOESI_CMP_token-L2cache.sm174
-rw-r--r--src/mem/protocol/MOESI_CMP_token-dir.sm866
-rw-r--r--src/mem/protocol/MOESI_CMP_token-dma.sm165
-rw-r--r--src/mem/protocol/MOESI_CMP_token-msg.sm54
-rw-r--r--src/mem/protocol/MOESI_CMP_token.slicc1
-rw-r--r--src/mem/protocol/MOESI_hammer-cache.sm1132
-rw-r--r--src/mem/protocol/MOESI_hammer-dir.sm920
-rw-r--r--src/mem/protocol/MOESI_hammer-dma.sm165
-rw-r--r--src/mem/protocol/MOESI_hammer-msg.sm119
-rw-r--r--src/mem/protocol/MOESI_hammer.slicc5
-rw-r--r--src/mem/protocol/RubySlicc_ComponentMapping.sm2
-rw-r--r--src/mem/protocol/RubySlicc_Util.sm1
-rw-r--r--src/mem/protocol/SConscript78
-rw-r--r--src/mem/protocol/SConsopts3
-rw-r--r--src/mem/request.hh2
-rw-r--r--src/mem/ruby/SConscript1
-rw-r--r--src/mem/ruby/buffers/MessageBuffer.cc23
-rw-r--r--src/mem/ruby/buffers/MessageBuffer.hh6
-rw-r--r--src/mem/ruby/common/Address.hh2
-rw-r--r--src/mem/ruby/common/DataBlock.hh6
-rw-r--r--src/mem/ruby/common/Debug.cc31
-rw-r--r--src/mem/ruby/common/Debug.hh1
-rw-r--r--src/mem/ruby/common/NetDest.cc5
-rw-r--r--src/mem/ruby/common/NetDest.hh4
-rw-r--r--src/mem/ruby/config/MI_example-homogeneous.rb13
-rw-r--r--src/mem/ruby/config/MI_example.rb2
-rw-r--r--src/mem/ruby/config/MOESI_CMP_token.rb92
-rw-r--r--src/mem/ruby/config/MOESI_hammer-homogeneous.rb109
-rw-r--r--src/mem/ruby/config/MOESI_hammer.rb41
-rw-r--r--src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb2
-rw-r--r--src/mem/ruby/libruby.cc6
-rw-r--r--src/mem/ruby/libruby.hh2
-rw-r--r--src/mem/ruby/network/Network.cc27
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh30
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.cc11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.hh11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/NetworkHeader.hh11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.cc11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.hh11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.cc11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.cc11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.cc11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.hh11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/Router_d.cc11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/Router_d.hh10
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.cc11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.hh11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.cc11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.hh11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.cc11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.hh11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.cc11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.hh11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.cc11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.hh11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.cc11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.hh11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/flit_d.cc11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/flit_d.hh12
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/FlexibleConsumer.hh10
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc11
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh11
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/InVcState.cc11
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/InVcState.hh12
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh14
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.cc11
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh10
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.cc11
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh10
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.cc11
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.hh11
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/Router.cc11
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/Router.hh11
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.cc11
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.hh11
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/flit.cc11
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/flit.hh11
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.cc11
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh11
-rw-r--r--src/mem/ruby/network/orion/power_utils.cc42
-rw-r--r--src/mem/ruby/network/simple/SimpleNetwork.cc8
-rw-r--r--src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.cc (renamed from src/mem/slicc/ast/DeclAST.cc)17
-rw-r--r--src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh11
-rw-r--r--src/mem/ruby/slicc_interface/SConscript1
-rw-r--r--src/mem/ruby/system/CacheMemory.cc483
-rw-r--r--src/mem/ruby/system/CacheMemory.hh465
-rw-r--r--src/mem/ruby/system/DirectoryMemory.cc11
-rw-r--r--src/mem/ruby/system/PersistentTable.cc204
-rw-r--r--src/mem/ruby/system/PersistentTable.hh (renamed from src/mem/slicc/ast/InfixOperatorExprAST.hh)75
-rw-r--r--src/mem/ruby/system/SConscript2
-rw-r--r--src/mem/ruby/system/Sequencer.hh2
-rw-r--r--src/mem/ruby/system/System.hh5
-rw-r--r--src/mem/rubymem.cc240
-rw-r--r--src/mem/rubymem.hh28
-rw-r--r--src/mem/slicc/SConscript129
-rw-r--r--src/mem/slicc/__init__.py25
-rw-r--r--src/mem/slicc/ast/AST.hh94
-rw-r--r--src/mem/slicc/ast/AST.py63
-rw-r--r--src/mem/slicc/ast/ASTs.hh91
-rw-r--r--src/mem/slicc/ast/ActionDeclAST.cc98
-rw-r--r--src/mem/slicc/ast/ActionDeclAST.hh86
-rw-r--r--src/mem/slicc/ast/ActionDeclAST.py72
-rw-r--r--src/mem/slicc/ast/AssignStatementAST.cc76
-rw-r--r--src/mem/slicc/ast/AssignStatementAST.hh85
-rw-r--r--src/mem/slicc/ast/AssignStatementAST.py59
-rw-r--r--src/mem/slicc/ast/CheckAllocateStatementAST.cc72
-rw-r--r--src/mem/slicc/ast/CheckAllocateStatementAST.py47
-rw-r--r--src/mem/slicc/ast/CheckStopSlotsStatementAST.cc115
-rw-r--r--src/mem/slicc/ast/CheckStopSlotsStatementAST.hh85
-rw-r--r--src/mem/slicc/ast/CheckStopSlotsStatementAST.py74
-rw-r--r--src/mem/slicc/ast/ChipComponentAccessAST.cc244
-rw-r--r--src/mem/slicc/ast/ChipComponentAccessAST.hh101
-rw-r--r--src/mem/slicc/ast/ChipComponentAccessAST.py161
-rw-r--r--src/mem/slicc/ast/CopyHeadStatementAST.cc85
-rw-r--r--src/mem/slicc/ast/CopyHeadStatementAST.hh87
-rw-r--r--src/mem/slicc/ast/CopyHeadStatementAST.py52
-rw-r--r--src/mem/slicc/ast/DeclAST.py38
-rw-r--r--src/mem/slicc/ast/DeclListAST.hh84
-rw-r--r--src/mem/slicc/ast/DeclListAST.py53
-rw-r--r--src/mem/slicc/ast/EnqueueStatementAST.cc111
-rw-r--r--src/mem/slicc/ast/EnqueueStatementAST.hh93
-rw-r--r--src/mem/slicc/ast/EnqueueStatementAST.py86
-rw-r--r--src/mem/slicc/ast/EnumDeclAST.cc98
-rw-r--r--src/mem/slicc/ast/EnumDeclAST.hh86
-rw-r--r--src/mem/slicc/ast/EnumDeclAST.py71
-rw-r--r--src/mem/slicc/ast/EnumExprAST.hh85
-rw-r--r--src/mem/slicc/ast/EnumExprAST.py53
-rw-r--r--src/mem/slicc/ast/ExprAST.cc39
-rw-r--r--src/mem/slicc/ast/ExprAST.py45
-rw-r--r--src/mem/slicc/ast/ExprStatementAST.hh83
-rw-r--r--src/mem/slicc/ast/ExprStatementAST.py52
-rw-r--r--src/mem/slicc/ast/FormalParamAST.cc72
-rw-r--r--src/mem/slicc/ast/FormalParamAST.hh88
-rw-r--r--src/mem/slicc/ast/FormalParamAST.py52
-rw-r--r--src/mem/slicc/ast/FuncCallExprAST.cc224
-rw-r--r--src/mem/slicc/ast/FuncCallExprAST.hh89
-rw-r--r--src/mem/slicc/ast/FuncCallExprAST.py168
-rw-r--r--src/mem/slicc/ast/FuncDeclAST.cc112
-rw-r--r--src/mem/slicc/ast/FuncDeclAST.hh91
-rw-r--r--src/mem/slicc/ast/FuncDeclAST.py88
-rw-r--r--src/mem/slicc/ast/IfStatementAST.cc98
-rw-r--r--src/mem/slicc/ast/IfStatementAST.hh89
-rw-r--r--src/mem/slicc/ast/IfStatementAST.py74
-rw-r--r--src/mem/slicc/ast/InPortDeclAST.cc149
-rw-r--r--src/mem/slicc/ast/InPortDeclAST.hh91
-rw-r--r--src/mem/slicc/ast/InPortDeclAST.py130
-rw-r--r--src/mem/slicc/ast/InfixOperatorExprAST.cc121
-rw-r--r--src/mem/slicc/ast/InfixOperatorExprAST.py89
-rw-r--r--src/mem/slicc/ast/LiteralExprAST.py55
-rw-r--r--src/mem/slicc/ast/Location.cc87
-rw-r--r--src/mem/slicc/ast/Location.hh93
-rw-r--r--src/mem/slicc/ast/MachineAST.cc99
-rw-r--r--src/mem/slicc/ast/MachineAST.hh93
-rw-r--r--src/mem/slicc/ast/MachineAST.py81
-rw-r--r--src/mem/slicc/ast/MemberExprAST.cc72
-rw-r--r--src/mem/slicc/ast/MemberExprAST.hh83
-rw-r--r--src/mem/slicc/ast/MemberExprAST.py55
-rw-r--r--src/mem/slicc/ast/MethodCallExprAST.cc160
-rw-r--r--src/mem/slicc/ast/MethodCallExprAST.hh93
-rw-r--r--src/mem/slicc/ast/MethodCallExprAST.py130
-rw-r--r--src/mem/slicc/ast/NewExprAST.cc9
-rw-r--r--src/mem/slicc/ast/NewExprAST.hh20
-rw-r--r--src/mem/slicc/ast/NewExprAST.py47
-rw-r--r--src/mem/slicc/ast/ObjDeclAST.cc137
-rw-r--r--src/mem/slicc/ast/ObjDeclAST.hh86
-rw-r--r--src/mem/slicc/ast/ObjDeclAST.py94
-rw-r--r--src/mem/slicc/ast/OutPortDeclAST.cc79
-rw-r--r--src/mem/slicc/ast/OutPortDeclAST.hh89
-rw-r--r--src/mem/slicc/ast/OutPortDeclAST.py57
-rw-r--r--src/mem/slicc/ast/PairAST.hh86
-rw-r--r--src/mem/slicc/ast/PairAST.py36
-rw-r--r--src/mem/slicc/ast/PairListAST.py37
-rw-r--r--src/mem/slicc/ast/PeekStatementAST.cc115
-rw-r--r--src/mem/slicc/ast/PeekStatementAST.hh91
-rw-r--r--src/mem/slicc/ast/PeekStatementAST.py73
-rw-r--r--src/mem/slicc/ast/ReturnStatementAST.cc79
-rw-r--r--src/mem/slicc/ast/ReturnStatementAST.hh83
-rw-r--r--src/mem/slicc/ast/ReturnStatementAST.py54
-rw-r--r--src/mem/slicc/ast/StatementAST.hh88
-rw-r--r--src/mem/slicc/ast/StatementAST.py34
-rw-r--r--src/mem/slicc/ast/StatementListAST.cc86
-rw-r--r--src/mem/slicc/ast/StatementListAST.hh85
-rw-r--r--src/mem/slicc/ast/StatementListAST.py46
-rw-r--r--src/mem/slicc/ast/TransitionDeclAST.cc89
-rw-r--r--src/mem/slicc/ast/TransitionDeclAST.hh89
-rw-r--r--src/mem/slicc/ast/TransitionDeclAST.py65
-rw-r--r--src/mem/slicc/ast/TypeAST.py53
-rw-r--r--src/mem/slicc/ast/TypeDeclAST.hh86
-rw-r--r--src/mem/slicc/ast/TypeDeclAST.py61
-rw-r--r--src/mem/slicc/ast/TypeFieldAST.hh83
-rw-r--r--src/mem/slicc/ast/TypeFieldAST.py32
-rw-r--r--src/mem/slicc/ast/TypeFieldEnumAST.cc82
-rw-r--r--src/mem/slicc/ast/TypeFieldEnumAST.hh86
-rw-r--r--src/mem/slicc/ast/TypeFieldEnumAST.py59
-rw-r--r--src/mem/slicc/ast/TypeFieldMemberAST.cc84
-rw-r--r--src/mem/slicc/ast/TypeFieldMemberAST.hh91
-rw-r--r--src/mem/slicc/ast/TypeFieldMemberAST.py57
-rw-r--r--src/mem/slicc/ast/TypeFieldMethodAST.cc81
-rw-r--r--src/mem/slicc/ast/TypeFieldMethodAST.hh87
-rw-r--r--src/mem/slicc/ast/TypeFieldMethodAST.py50
-rw-r--r--src/mem/slicc/ast/VarExprAST.cc76
-rw-r--r--src/mem/slicc/ast/VarExprAST.hh86
-rw-r--r--src/mem/slicc/ast/VarExprAST.py66
-rw-r--r--src/mem/slicc/ast/__init__.py69
-rw-r--r--src/mem/slicc/generate/__init__.py0
-rw-r--r--src/mem/slicc/generate/dot.py42
-rw-r--r--src/mem/slicc/generate/html.py80
-rw-r--r--src/mem/slicc/generate/tex.py71
-rw-r--r--src/mem/slicc/generator/html_gen.cc125
-rw-r--r--src/mem/slicc/generator/html_gen.hh49
-rw-r--r--src/mem/slicc/generator/mif_gen.cc1718
-rw-r--r--src/mem/slicc/generator/mif_gen.hh45
-rw-r--r--src/mem/slicc/main.cc246
-rw-r--r--src/mem/slicc/main.hh48
-rw-r--r--src/mem/slicc/main.py100
-rw-r--r--src/mem/slicc/parser.py667
-rw-r--r--src/mem/slicc/parser/lexer.ll125
-rw-r--r--src/mem/slicc/parser/parser.py563
-rw-r--r--src/mem/slicc/parser/parser.yy360
-rw-r--r--src/mem/slicc/slicc_global.hh125
-rw-r--r--src/mem/slicc/symbols/Action.hh52
-rw-r--r--src/mem/slicc/symbols/Action.py38
-rw-r--r--src/mem/slicc/symbols/Event.hh45
-rw-r--r--src/mem/slicc/symbols/Event.py34
-rw-r--r--src/mem/slicc/symbols/Func.cc143
-rw-r--r--src/mem/slicc/symbols/Func.hh96
-rw-r--r--src/mem/slicc/symbols/Func.py107
-rw-r--r--src/mem/slicc/symbols/State.hh45
-rw-r--r--src/mem/slicc/symbols/State.py34
-rw-r--r--src/mem/slicc/symbols/StateMachine.cc1481
-rw-r--r--src/mem/slicc/symbols/StateMachine.hh156
-rw-r--r--src/mem/slicc/symbols/StateMachine.py1164
-rw-r--r--src/mem/slicc/symbols/Symbol.hh100
-rw-r--r--src/mem/slicc/symbols/Symbol.py78
-rw-r--r--src/mem/slicc/symbols/SymbolTable.cc327
-rw-r--r--src/mem/slicc/symbols/SymbolTable.hh121
-rw-r--r--src/mem/slicc/symbols/SymbolTable.py221
-rw-r--r--src/mem/slicc/symbols/Transition.cc173
-rw-r--r--src/mem/slicc/symbols/Transition.hh120
-rw-r--r--src/mem/slicc/symbols/Transition.py61
-rw-r--r--src/mem/slicc/symbols/Type.cc779
-rw-r--r--src/mem/slicc/symbols/Type.hh155
-rw-r--r--src/mem/slicc/symbols/Type.py652
-rw-r--r--src/mem/slicc/symbols/Var.hh98
-rw-r--r--src/mem/slicc/symbols/Var.py50
-rw-r--r--src/mem/slicc/symbols/__init__.py38
-rw-r--r--src/mem/slicc/util.py75
-rw-r--r--src/mem/translating_port.cc2
-rw-r--r--src/mem/vport.cc1
-rw-r--r--src/python/SConscript5
-rw-r--r--src/python/m5/SimObject.py79
-rw-r--r--src/python/m5/__init__.py102
-rw-r--r--src/python/m5/main.py2
-rw-r--r--src/python/m5/params.py39
-rw-r--r--src/python/m5/simulate.py3
-rw-r--r--src/python/m5/ticks.py2
-rw-r--r--src/python/m5/trace.py2
-rw-r--r--src/python/m5/util/__init__.py149
-rw-r--r--src/python/m5/util/attrdict.py12
-rw-r--r--src/python/m5/util/code_formatter.py5
-rw-r--r--src/python/m5/util/convert.py (renamed from src/python/m5/convert.py)0
-rw-r--r--src/python/m5/util/grammar.py4
-rw-r--r--src/python/m5/util/jobfile.py10
-rw-r--r--src/python/m5/util/misc.py87
-rw-r--r--src/python/m5/util/smartdict.py (renamed from src/python/m5/smartdict.py)0
-rw-r--r--src/sim/System.py5
-rw-r--r--src/sim/arguments.cc5
-rw-r--r--src/sim/eventq.hh2
-rw-r--r--src/sim/process.cc28
-rw-r--r--src/sim/process.hh12
-rw-r--r--src/sim/pseudo_inst.cc4
-rw-r--r--src/sim/syscall_emul.cc215
-rw-r--r--src/sim/syscall_emul.hh238
-rw-r--r--src/sim/system.cc3
-rw-r--r--src/sim/system.hh8
593 files changed, 23165 insertions, 18493 deletions
diff --git a/src/SConscript b/src/SConscript
index d96922b49..d02d2a6e7 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -49,7 +49,7 @@ Import('*')
# Children need to see the environment
Export('env')
-build_env = dict([(opt, env[opt]) for opt in export_vars])
+build_env = [(opt, env[opt]) for opt in export_vars]
########################################################################
# Code for adding source files of various types
@@ -132,15 +132,15 @@ class PySource(SourceFile):
modpath = '.'.join(modpath)
arcpath = path + [ self.basename ]
- debugname = self.snode.abspath
- if not exists(debugname):
- debugname = self.tnode.abspath
+ abspath = self.snode.abspath
+ if not exists(abspath):
+ abspath = self.tnode.abspath
self.package = package
self.modname = modname
self.modpath = modpath
self.arcname = joinpath(*arcpath)
- self.debugname = debugname
+ self.abspath = abspath
self.compiled = File(self.filename + 'c')
self.assembly = File(self.filename + '.s')
self.symname = "PyEMB_" + PySource.invalid_sym_char.sub('_', modpath)
@@ -228,9 +228,6 @@ env.Append(CPPPATH=Dir('.'))
for extra_dir in extras_dir_list:
env.Append(CPPPATH=Dir(extra_dir))
-# Add a flag defining what THE_ISA should be for all compilation
-env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())])
-
# Workaround for bug in SCons version > 0.97d20071212
# Scons bug id: 2006 M5 Bug id: 308
for root, dirs, files in os.walk(base_dir, topdown=True):
@@ -261,11 +258,38 @@ for extra_dir in extras_dir_list:
for opt in export_vars:
env.ConfigFile(opt)
+def makeTheISA(source, target, env):
+ f = file(str(target[0]), 'w')
+
+ isas = [ src.get_contents() for src in source ]
+ target = env['TARGET_ISA']
+ def define(isa):
+ return isa.upper() + '_ISA'
+
+ def namespace(isa):
+ return isa[0].upper() + isa[1:].lower() + 'ISA'
+
+
+ print >>f, '#ifndef __CONFIG_THE_ISA_HH__'
+ print >>f, '#define __CONFIG_THE_ISA_HH__'
+ print >>f
+ for i,isa in enumerate(isas):
+ print >>f, '#define %s %d' % (define(isa), i + 1)
+ print >>f
+ print >>f, '#define THE_ISA %s' % (define(target))
+ print >>f, '#define TheISA %s' % (namespace(target))
+ print >>f
+ print >>f, '#endif // __CONFIG_THE_ISA_HH__'
+
+env.Command('config/the_isa.hh', map(Value, all_isa_list), makeTheISA)
+
########################################################################
#
# Prevent any SimObjects from being added after this point, they
# should all have been added in the SConscripts above
#
+SimObject.fixed = True
+
class DictImporter(object):
'''This importer takes a dictionary of arbitrary module names that
map to arbitrary filenames.'''
@@ -283,7 +307,7 @@ class DictImporter(object):
self.installed = set()
def find_module(self, fullname, path):
- if fullname == 'defines':
+ if fullname == 'm5.defines':
return self
if fullname == 'm5.objects':
@@ -293,7 +317,7 @@ class DictImporter(object):
return None
source = self.modules.get(fullname, None)
- if source is not None and exists(source.snode.abspath):
+ if source is not None and fullname.startswith('m5.objects'):
return self
return None
@@ -308,28 +332,31 @@ class DictImporter(object):
mod.__path__ = fullname.split('.')
return mod
- if fullname == 'defines':
- mod.__dict__['buildEnv'] = build_env
+ if fullname == 'm5.defines':
+ mod.__dict__['buildEnv'] = m5.util.SmartDict(build_env)
return mod
source = self.modules[fullname]
if source.modname == '__init__':
mod.__path__ = source.modpath
- mod.__file__ = source.snode.abspath
+ mod.__file__ = source.abspath
- exec file(source.snode.abspath, 'r') in mod.__dict__
+ exec file(source.abspath, 'r') in mod.__dict__
return mod
+import m5.SimObject
+import m5.params
+
+m5.SimObject.clear()
+m5.params.clear()
+
# install the python importer so we can grab stuff from the source
# tree itself. We can't have SimObjects added after this point or
# else we won't know about them for the rest of the stuff.
-SimObject.fixed = True
importer = DictImporter(PySource.modules)
sys.meta_path[0:0] = [ importer ]
-import m5
-
# import all sim objects so we can populate the all_objects list
# make sure that we're working with a list, then let's sort it
for modname in SimObject.modnames:
@@ -346,6 +373,12 @@ all_enums = m5.params.allEnums
all_params = {}
for name,obj in sorted(sim_objects.iteritems()):
for param in obj._params.local.values():
+ # load the ptype attribute now because it depends on the
+ # current version of SimObject.allClasses, but when scons
+ # actually uses the value, all versions of
+ # SimObject.allClasses will have been loaded
+ param.ptype
+
if not hasattr(param, 'swig_decl'):
continue
pname = param.ptype_str
@@ -365,13 +398,27 @@ depends = [ PySource.modules[dep].tnode for dep in module_depends ]
#
# Generate Python file containing a dict specifying the current
-# build_env flags.
+# buildEnv flags.
def makeDefinesPyFile(target, source, env):
- f = file(str(target[0]), 'w')
build_env, hg_info = [ x.get_contents() for x in source ]
- print >>f, "buildEnv = %s" % build_env
- print >>f, "hgRev = '%s'" % hg_info
- f.close()
+
+ code = m5.util.code_formatter()
+ code("""
+import m5.internal
+import m5.util
+
+buildEnv = m5.util.SmartDict($build_env)
+hgRev = '$hg_info'
+
+compileDate = m5.internal.core.compileDate
+_globals = globals()
+for key,val in m5.internal.core.__dict__.iteritems():
+ if key.startswith('flag_'):
+ flag = key[5:]
+ _globals[flag] = val
+del _globals
+""")
+ code.write(str(target[0]))
defines_info = [ Value(build_env), Value(env['HG_INFO']) ]
# Generate a file with all of the compile options in it
@@ -467,12 +514,7 @@ for name,simobj in sorted(sim_objects.iteritems()):
# Generate any parameter header files needed
params_i_files = []
for name,param in all_params.iteritems():
- if isinstance(param, m5.params.VectorParamDesc):
- ext = 'vptype'
- else:
- ext = 'ptype'
-
- i_file = File('params/%s_%s.i' % (name, ext))
+ i_file = File('params/%s_%s.i' % (name, param.file_ext))
params_i_files.append(i_file)
env.Command(i_file, Value(name), createSwigParam)
env.Depends(i_file, depends)
@@ -850,7 +892,7 @@ def objectifyPyFile(target, source, env):
dst = file(str(target[0]), 'w')
pysource = PySource.tnodes[source[0]]
- compiled = compile(src, pysource.debugname, 'exec')
+ compiled = compile(src, pysource.abspath, 'exec')
marshalled = marshal.dumps(compiled)
compressed = zlib.compress(marshalled)
data = compressed
diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc
index e93e16711..ff6de8d03 100644
--- a/src/arch/alpha/faults.cc
+++ b/src/arch/alpha/faults.cc
@@ -144,7 +144,7 @@ DtbFault::invoke(ThreadContext *tc)
// read, like the EV5). The EV6 approach is cleaner and seems to
// work with EV5 PAL code, but not the other way around.
if (!tc->misspeculating() &&
- reqFlags.noneSet(Request::VPTE|Request::NO_FAULT)) {
+ reqFlags.noneSet(Request::VPTE | Request::PREFETCH)) {
// set VA register with faulting address
tc->setMiscRegNoEffect(IPR_VA, vaddr);
diff --git a/src/arch/alpha/isa.cc b/src/arch/alpha/isa.cc
index eee391a0d..8b6da3649 100644
--- a/src/arch/alpha/isa.cc
+++ b/src/arch/alpha/isa.cc
@@ -36,7 +36,7 @@ namespace AlphaISA
{
void
-ISA::serialize(std::ostream &os)
+ISA::serialize(EventManager *em, std::ostream &os)
{
SERIALIZE_SCALAR(fpcr);
SERIALIZE_SCALAR(uniq);
@@ -46,7 +46,7 @@ ISA::serialize(std::ostream &os)
}
void
-ISA::unserialize(Checkpoint *cp, const std::string &section)
+ISA::unserialize(EventManager *em, Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_SCALAR(fpcr);
UNSERIALIZE_SCALAR(uniq);
diff --git a/src/arch/alpha/isa.hh b/src/arch/alpha/isa.hh
index 622d1da4c..574b50841 100644
--- a/src/arch/alpha/isa.hh
+++ b/src/arch/alpha/isa.hh
@@ -83,8 +83,9 @@ namespace AlphaISA
intr_flag = 0;
}
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string &section);
+ void serialize(EventManager *em, std::ostream &os);
+ void unserialize(EventManager *em, Checkpoint *cp,
+ const std::string &section);
void reset(std::string core_name, ThreadID num_threads,
unsigned num_vpes, BaseCPU *_cpu)
diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa
index cb43fcb74..52e124ad5 100644
--- a/src/arch/alpha/isa/decoder.isa
+++ b/src/arch/alpha/isa/decoder.isa
@@ -627,7 +627,7 @@ decode OPCODE default Unknown::unknown() {
format MiscPrefetch {
0xf800: wh64({{ EA = Rb & ~ULL(63); }},
{{ xc->writeHint(EA, 64, memAccessFlags); }},
- mem_flags = NO_FAULT,
+ mem_flags = PREFETCH,
inst_flags = [IsMemRef, IsDataPrefetch,
IsStore, MemWriteOp]);
}
diff --git a/src/arch/alpha/isa/mem.isa b/src/arch/alpha/isa/mem.isa
index fedfbf55d..b1703221f 100644
--- a/src/arch/alpha/isa/mem.isa
+++ b/src/arch/alpha/isa/mem.isa
@@ -548,7 +548,7 @@ def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
pf_flags = makeList(pf_flags)
inst_flags = makeList(inst_flags)
- pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
+ pf_mem_flags = mem_flags + pf_flags + ['PREFETCH']
pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
'IsDataPrefetch', 'MemReadOp']
diff --git a/src/arch/alpha/linux/linux.hh b/src/arch/alpha/linux/linux.hh
index c622c5ef1..c728ce1fb 100644
--- a/src/arch/alpha/linux/linux.hh
+++ b/src/arch/alpha/linux/linux.hh
@@ -105,6 +105,7 @@ class AlphaLinux : public Linux
static const unsigned TIOCISATTY_ = 0x2000745e;
static const unsigned TIOCGETS_ = 0x402c7413;
static const unsigned TIOCGETA_ = 0x40127417;
+ static const unsigned TCSETAW_ = 0x80147419; // 2.6.15 kernel
//@}
/// For table().
@@ -125,6 +126,21 @@ class AlphaLinux : public Linux
TGT_RLIMIT_MEMLOCK = 9,
TGT_RLIMIT_LOCKS = 10
};
+
+ typedef struct {
+ int64_t uptime; /* Seconds since boot */
+ uint64_t loads[3]; /* 1, 5, and 15 minute load averages */
+ uint64_t totalram; /* Total usable main memory size */
+ uint64_t freeram; /* Available memory size */
+ uint64_t sharedram; /* Amount of shared memory */
+ uint64_t bufferram; /* Memory used by buffers */
+ uint64_t totalswap; /* Total swap space size */
+ uint64_t freeswap; /* swap space still available */
+ uint16_t procs; /* Number of current processes */
+ uint64_t totalhigh; /* Total high memory size */
+ uint64_t freehigh; /* Available high memory size */
+ uint64_t mem_unit; /* Memory unit size in bytes */
+ } tgt_sysinfo;
};
#endif // __ALPHA_ALPHA_LINUX_LINUX_HH__
diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc
index 9886c7ea7..a653d7845 100644
--- a/src/arch/alpha/linux/process.cc
+++ b/src/arch/alpha/linux/process.cc
@@ -48,7 +48,8 @@ static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
+ int index = 0;
+ TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, index));
strcpy(name->sysname, "Linux");
strcpy(name->nodename, "m5.eecs.umich.edu");
@@ -67,13 +68,15 @@ static SyscallReturn
osf_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- unsigned op = process->getSyscallArg(tc, 0);
+ int index = 0;
+ unsigned op = process->getSyscallArg(tc, index);
+ Addr bufPtr = process->getSyscallArg(tc, index);
// unsigned nbytes = process->getSyscallArg(tc, 2);
switch (op) {
case 45: { // GSI_IEEE_FP_CONTROL
- TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1));
+ TypedBufferArg<uint64_t> fpcr(bufPtr);
// I don't think this exactly matches the HW FPCR
*fpcr = 0;
fpcr.copyOut(tc->getMemPort());
@@ -94,13 +97,15 @@ static SyscallReturn
osf_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- unsigned op = process->getSyscallArg(tc, 0);
+ int index = 0;
+ unsigned op = process->getSyscallArg(tc, index);
+ Addr bufPtr = process->getSyscallArg(tc, index);
// unsigned nbytes = process->getSyscallArg(tc, 2);
switch (op) {
case 14: { // SSI_IEEE_FP_CONTROL
- TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1));
+ TypedBufferArg<uint64_t> fpcr(bufPtr);
// I don't think this exactly matches the HW FPCR
fpcr.copyIn(tc->getMemPort());
DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
@@ -440,7 +445,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = {
/* 315 */ SyscallDesc("munlock", unimplementedFunc),
/* 316 */ SyscallDesc("mlockall", unimplementedFunc),
/* 317 */ SyscallDesc("munlockall", unimplementedFunc),
- /* 318 */ SyscallDesc("sysinfo", unimplementedFunc),
+ /* 318 */ SyscallDesc("sysinfo", sysinfoFunc<AlphaLinux>),
/* 319 */ SyscallDesc("_sysctl", unimplementedFunc),
/* 320 */ SyscallDesc("was sys_idle", unimplementedFunc),
/* 321 */ SyscallDesc("oldumount", unimplementedFunc),
diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc
index 6aad45da8..9d75d5fa1 100644
--- a/src/arch/alpha/process.cc
+++ b/src/arch/alpha/process.cc
@@ -193,10 +193,10 @@ AlphaLiveProcess::startup()
}
AlphaISA::IntReg
-AlphaLiveProcess::getSyscallArg(ThreadContext *tc, int i)
+AlphaLiveProcess::getSyscallArg(ThreadContext *tc, int &i)
{
assert(i < 6);
- return tc->readIntReg(FirstArgumentReg + i);
+ return tc->readIntReg(FirstArgumentReg + i++);
}
void
diff --git a/src/arch/alpha/process.hh b/src/arch/alpha/process.hh
index 6d083c5ac..36b25a48e 100644
--- a/src/arch/alpha/process.hh
+++ b/src/arch/alpha/process.hh
@@ -44,7 +44,7 @@ class AlphaLiveProcess : public LiveProcess
void argsInit(int intSize, int pageSize);
public:
- AlphaISA::IntReg getSyscallArg(ThreadContext *tc, int i);
+ AlphaISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
void setSyscallArg(ThreadContext *tc, int i, AlphaISA::IntReg val);
void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
};
diff --git a/src/arch/alpha/tru64/process.cc b/src/arch/alpha/tru64/process.cc
index 8fa3cdeda..b039fbe19 100644
--- a/src/arch/alpha/tru64/process.cc
+++ b/src/arch/alpha/tru64/process.cc
@@ -45,7 +45,8 @@ static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- TypedBufferArg<AlphaTru64::utsname> name(process->getSyscallArg(tc, 0));
+ int index = 0;
+ TypedBufferArg<AlphaTru64::utsname> name(process->getSyscallArg(tc, index));
strcpy(name->sysname, "OSF1");
strcpy(name->nodename, "m5.eecs.umich.edu");
@@ -62,35 +63,36 @@ static SyscallReturn
getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- unsigned op = process->getSyscallArg(tc, 0);
- unsigned nbytes = process->getSyscallArg(tc, 2);
+ int index = 0;
+ unsigned op = process->getSyscallArg(tc, index);
+ Addr bufPtr = process->getSyscallArg(tc, index);
+ unsigned nbytes = process->getSyscallArg(tc, index);
switch (op) {
case AlphaTru64::GSI_MAX_CPU: {
- TypedBufferArg<uint32_t> max_cpu(process->getSyscallArg(tc, 1));
+ TypedBufferArg<uint32_t> max_cpu(bufPtr);
*max_cpu = htog((uint32_t)process->numCpus());
max_cpu.copyOut(tc->getMemPort());
return 1;
}
case AlphaTru64::GSI_CPUS_IN_BOX: {
- TypedBufferArg<uint32_t> cpus_in_box(process->getSyscallArg(tc, 1));
+ TypedBufferArg<uint32_t> cpus_in_box(bufPtr);
*cpus_in_box = htog((uint32_t)process->numCpus());
cpus_in_box.copyOut(tc->getMemPort());
return 1;
}
case AlphaTru64::GSI_PHYSMEM: {
- TypedBufferArg<uint64_t> physmem(process->getSyscallArg(tc, 1));
+ TypedBufferArg<uint64_t> physmem(bufPtr);
*physmem = htog((uint64_t)1024 * 1024); // physical memory in KB
physmem.copyOut(tc->getMemPort());
return 1;
}
case AlphaTru64::GSI_CPU_INFO: {
- TypedBufferArg<AlphaTru64::cpu_info>
- infop(process->getSyscallArg(tc, 1));
+ TypedBufferArg<AlphaTru64::cpu_info> infop(bufPtr);
infop->current_cpu = htog(0);
infop->cpus_in_box = htog(process->numCpus());
@@ -107,14 +109,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
}
case AlphaTru64::GSI_PROC_TYPE: {
- TypedBufferArg<uint64_t> proc_type(process->getSyscallArg(tc, 1));
+ TypedBufferArg<uint64_t> proc_type(bufPtr);
*proc_type = htog((uint64_t)11);
proc_type.copyOut(tc->getMemPort());
return 1;
}
case AlphaTru64::GSI_PLATFORM_NAME: {
- BufferArg bufArg(process->getSyscallArg(tc, 1), nbytes);
+ BufferArg bufArg(bufPtr, nbytes);
strncpy((char *)bufArg.bufferPtr(),
"COMPAQ Professional Workstation XP1000",
nbytes);
@@ -123,7 +125,7 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
}
case AlphaTru64::GSI_CLK_TCK: {
- TypedBufferArg<uint64_t> clk_hz(process->getSyscallArg(tc, 1));
+ TypedBufferArg<uint64_t> clk_hz(bufPtr);
*clk_hz = htog((uint64_t)1024);
clk_hz.copyOut(tc->getMemPort());
return 1;
@@ -142,12 +144,13 @@ static SyscallReturn
setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- unsigned op = process->getSyscallArg(tc, 0);
+ int index = 0;
+ unsigned op = process->getSyscallArg(tc, index);
switch (op) {
case AlphaTru64::SSI_IEEE_FP_CONTROL:
warn("setsysinfo: ignoring ieee_set_fp_control() arg 0x%x\n",
- process->getSyscallArg(tc, 1));
+ process->getSyscallArg(tc, index));
break;
default:
@@ -165,17 +168,19 @@ tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
{
using namespace std;
- int id = process->getSyscallArg(tc, 0); // table ID
- int index = process->getSyscallArg(tc, 1); // index into table
+ int argIndex = 0;
+ int id = process->getSyscallArg(tc, argIndex); // table ID
+ int index = process->getSyscallArg(tc, argIndex); // index into table
+ Addr bufPtr = process->getSyscallArg(tc, argIndex);
// arg 2 is buffer pointer; type depends on table ID
- int nel = process->getSyscallArg(tc, 3); // number of elements
- int lel = process->getSyscallArg(tc, 4); // expected element size
+ int nel = process->getSyscallArg(tc, argIndex); // number of elements
+ int lel = process->getSyscallArg(tc, argIndex); // expected element size
switch (id) {
case AlphaTru64::TBL_SYSINFO: {
if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo))
return -EINVAL;
- TypedBufferArg<Tru64::tbl_sysinfo> elp(process->getSyscallArg(tc, 2));
+ TypedBufferArg<Tru64::tbl_sysinfo> elp(bufPtr);
const int clk_hz = one_million;
elp->si_user = htog(curTick / (Clock::Frequency / clk_hz));
diff --git a/src/arch/alpha/tru64/tru64.hh b/src/arch/alpha/tru64/tru64.hh
index 4ba35fc50..0ee12973c 100644
--- a/src/arch/alpha/tru64/tru64.hh
+++ b/src/arch/alpha/tru64/tru64.hh
@@ -99,6 +99,7 @@ class AlphaTru64 : public Tru64
static const unsigned TIOCISATTY_ = 0x2000745e;
static const unsigned TIOCGETS_ = 0x402c7413;
static const unsigned TIOCGETA_ = 0x40127417;
+ static const unsigned TCSETAW_ = 0x80147419;
//@}
//@{
diff --git a/src/arch/arm/ArmInterrupts.py b/src/arch/arm/ArmInterrupts.py
new file mode 100644
index 000000000..f21d49e95
--- /dev/null
+++ b/src/arch/arm/ArmInterrupts.py
@@ -0,0 +1,33 @@
+# Copyright (c) 2009 ARM Limited
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Ali Saidi
+
+from m5.SimObject import SimObject
+
+class ArmInterrupts(SimObject):
+ type = 'ArmInterrupts'
+ cxx_class = 'ArmISA::Interrupts'
diff --git a/src/python/m5/environment.py b/src/arch/arm/ArmSystem.py
index bea0bc1d0..872776c69 100644
--- a/src/python/m5/environment.py
+++ b/src/arch/arm/ArmSystem.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2005 The Regents of The University of Michigan
+# Copyright (c) 2009 ARM Limited
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -24,20 +24,12 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
-# Authors: Nathan Binkert
-# Steve Reinhardt
+# Authors: Ali Saidi
-import os
+from m5.params import *
-# import the m5 compile options
-import defines
+from System import System
-# make a SmartDict out of the build options for our local use
-import smartdict
-build_env = smartdict.SmartDict()
-build_env.update(defines.m5_build_env)
-
-# make a SmartDict out of the OS environment too
-env = smartdict.SmartDict()
-env.update(os.environ)
+class ArmSystem(System):
+ type = 'ArmSystem'
diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript
index 55ecabdc3..92a4193f1 100644
--- a/src/arch/arm/SConscript
+++ b/src/arch/arm/SConscript
@@ -1,6 +1,7 @@
# -*- mode:python -*-
# Copyright (c) 2007-2008 The Florida State University
+# Copyright (c) 2009 ARM Limited
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -27,6 +28,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Stephen Hines
+# Ali Saidi
Import('*')
@@ -43,15 +45,20 @@ if env['TARGET_ISA'] == 'arm':
Source('pagetable.cc')
Source('tlb.cc')
Source('vtophys.cc')
+ Source('utility.cc')
SimObject('ArmNativeTrace.py')
SimObject('ArmTLB.py')
TraceFlag('Arm')
-
+ TraceFlag('Faults', "Trace Exceptions, interrupts, svc/swi")
if env['FULL_SYSTEM']:
- #Insert Full-System Files Here
- pass
+ Source('interrupts.cc')
+ Source('stacktrace.cc')
+ Source('system.cc')
+
+ SimObject('ArmInterrupts.py')
+ SimObject('ArmSystem.py')
else:
Source('process.cc')
Source('linux/linux.cc')
diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc
index 3d882c97f..b7dd2d503 100644
--- a/src/arch/arm/faults.cc
+++ b/src/arch/arm/faults.cc
@@ -26,488 +26,114 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * Authors: Gabe Black
- * Stephen Hines
+ * Authors: Ali Saidi
+ * Gabe Black
*/
#include "arch/arm/faults.hh"
#include "cpu/thread_context.hh"
#include "cpu/base.hh"
#include "base/trace.hh"
-#if !FULL_SYSTEM
-#include "sim/process.hh"
-#include "mem/page_table.hh"
-#endif
namespace ArmISA
{
-FaultName MachineCheckFault::_name = "Machine Check";
-FaultVect MachineCheckFault::_vect = 0x0401;
-FaultStat MachineCheckFault::_count;
+template<> ArmFaultBase::FaultVals ArmFault<Reset>::vals =
+ {"reset", 0x00, MODE_SVC, 0, 0, true, true};
-FaultName AlignmentFault::_name = "Alignment";
-FaultVect AlignmentFault::_vect = 0x0301;
-FaultStat AlignmentFault::_count;
+template<> ArmFaultBase::FaultVals ArmFault<UndefinedInstruction>::vals =
+ {"Undefined Instruction", 0x04, MODE_UNDEFINED, 4 ,2, false, false} ;
-FaultName ResetFault::_name = "Reset Fault";
-#if FULL_SYSTEM
-FaultVect ResetFault::_vect = 0xBFC00000;
-#else
-FaultVect ResetFault::_vect = 0x001;
-#endif
-FaultStat ResetFault::_count;
+template<> ArmFaultBase::FaultVals ArmFault<SupervisorCall>::vals =
+ {"Supervisor Call", 0x08, MODE_SVC, 4, 2, false, false};
-FaultName AddressErrorFault::_name = "Address Error";
-FaultVect AddressErrorFault::_vect = 0x0180;
-FaultStat AddressErrorFault::_count;
+template<> ArmFaultBase::FaultVals ArmFault<PrefetchAbort>::vals =
+ {"Prefetch Abort", 0x0C, MODE_ABORT, 4, 4, true, false};
-FaultName StoreAddressErrorFault::_name = "Store Address Error";
-FaultVect StoreAddressErrorFault::_vect = 0x0180;
-FaultStat StoreAddressErrorFault::_count;
+template<> ArmFaultBase::FaultVals ArmFault<DataAbort>::vals =
+ {"Data Abort", 0x10, MODE_ABORT, 8, 8, true, false};
+template<> ArmFaultBase::FaultVals ArmFault<Interrupt>::vals =
+ {"IRQ", 0x18, MODE_IRQ, 4, 4, true, false};
-FaultName SystemCallFault::_name = "Syscall";
-FaultVect SystemCallFault::_vect = 0x0180;
-FaultStat SystemCallFault::_count;
+template<> ArmFaultBase::FaultVals ArmFault<FastInterrupt>::vals =
+ {"FIQ", 0x1C, MODE_FIQ, 4, 4, true, true};
-FaultName CoprocessorUnusableFault::_name = "Coprocessor Unusable Fault";
-FaultVect CoprocessorUnusableFault::_vect = 0x180;
-FaultStat CoprocessorUnusableFault::_count;
-
-FaultName ReservedInstructionFault::_name = "Reserved Instruction Fault";
-FaultVect ReservedInstructionFault::_vect = 0x0180;
-FaultStat ReservedInstructionFault::_count;
-
-FaultName ThreadFault::_name = "Thread Fault";
-FaultVect ThreadFault::_vect = 0x00F1;
-FaultStat ThreadFault::_count;
-
-
-FaultName ArithmeticFault::_name = "Arithmetic Overflow Exception";
-FaultVect ArithmeticFault::_vect = 0x180;
-FaultStat ArithmeticFault::_count;
-
-FaultName UnimplementedOpcodeFault::_name = "opdec";
-FaultVect UnimplementedOpcodeFault::_vect = 0x0481;
-FaultStat UnimplementedOpcodeFault::_count;
-
-FaultName InterruptFault::_name = "interrupt";
-FaultVect InterruptFault::_vect = 0x0180;
-FaultStat InterruptFault::_count;
-
-FaultName TrapFault::_name = "Trap";
-FaultVect TrapFault::_vect = 0x0180;
-FaultStat TrapFault::_count;
-
-FaultName BreakpointFault::_name = "Breakpoint";
-FaultVect BreakpointFault::_vect = 0x0180;
-FaultStat BreakpointFault::_count;
-
-
-FaultName ItbInvalidFault::_name = "Invalid TLB Entry Exception (I-Fetch/LW)";
-FaultVect ItbInvalidFault::_vect = 0x0180;
-FaultStat ItbInvalidFault::_count;
-
-FaultName ItbPageFault::_name = "itbmiss";
-FaultVect ItbPageFault::_vect = 0x0181;
-FaultStat ItbPageFault::_count;
-
-FaultName ItbMissFault::_name = "itbmiss";
-FaultVect ItbMissFault::_vect = 0x0181;
-FaultStat ItbMissFault::_count;
-
-FaultName ItbAcvFault::_name = "iaccvio";
-FaultVect ItbAcvFault::_vect = 0x0081;
-FaultStat ItbAcvFault::_count;
-
-FaultName ItbRefillFault::_name = "TLB Refill Exception (I-Fetch/LW)";
-FaultVect ItbRefillFault::_vect = 0x0180;
-FaultStat ItbRefillFault::_count;
-
-FaultName NDtbMissFault::_name = "dtb_miss_single";
-FaultVect NDtbMissFault::_vect = 0x0201;
-FaultStat NDtbMissFault::_count;
-
-FaultName PDtbMissFault::_name = "dtb_miss_double";
-FaultVect PDtbMissFault::_vect = 0x0281;
-FaultStat PDtbMissFault::_count;
-
-FaultName DtbPageFault::_name = "dfault";
-FaultVect DtbPageFault::_vect = 0x0381;
-FaultStat DtbPageFault::_count;
-
-FaultName DtbAcvFault::_name = "dfault";
-FaultVect DtbAcvFault::_vect = 0x0381;
-FaultStat DtbAcvFault::_count;
-
-FaultName DtbInvalidFault::_name = "Invalid TLB Entry Exception (Store)";
-FaultVect DtbInvalidFault::_vect = 0x0180;
-FaultStat DtbInvalidFault::_count;
-
-FaultName DtbRefillFault::_name = "TLB Refill Exception (Store)";
-FaultVect DtbRefillFault::_vect = 0x0180;
-FaultStat DtbRefillFault::_count;
-
-FaultName TLBModifiedFault::_name = "TLB Modified Exception";
-FaultVect TLBModifiedFault::_vect = 0x0180;
-FaultStat TLBModifiedFault::_count;
-
-FaultName FloatEnableFault::_name = "float_enable_fault";
-FaultVect FloatEnableFault::_vect = 0x0581;
-FaultStat FloatEnableFault::_count;
-
-FaultName IntegerOverflowFault::_name = "Integer Overflow Fault";
-FaultVect IntegerOverflowFault::_vect = 0x0501;
-FaultStat IntegerOverflowFault::_count;
-
-FaultName DspStateDisabledFault::_name = "DSP Disabled Fault";
-FaultVect DspStateDisabledFault::_vect = 0x001a;
-FaultStat DspStateDisabledFault::_count;
-
-#if FULL_SYSTEM
-void ArmFault::setHandlerPC(Addr HandlerBase, ThreadContext *tc)
-{
- tc->setPC(HandlerBase);
- tc->setNextPC(HandlerBase+sizeof(MachInst));
- tc->setNextNPC(HandlerBase+2*sizeof(MachInst));
-}
-
-void ArmFault::setExceptionState(ThreadContext *tc,uint8_t ExcCode)
-{
- // modify SRS Ctl - Save CSS, put ESS into CSS
- MiscReg stat = tc->readMiscReg(ArmISA::Status);
- if(bits(stat,Status_EXL) != 1 && bits(stat,Status_BEV) != 1)
- {
- // SRS Ctl is modified only if Status_EXL and Status_BEV are not set
- MiscReg srs = tc->readMiscReg(ArmISA::SRSCtl);
- uint8_t CSS,ESS;
- CSS = bits(srs,SRSCtl_CSS_HI,SRSCtl_CSS_LO);
- ESS = bits(srs,SRSCtl_ESS_HI,SRSCtl_ESS_LO);
- // Move CSS to PSS
- replaceBits(srs,SRSCtl_PSS_HI,SRSCtl_PSS_LO,CSS);
- // Move ESS to CSS
- replaceBits(srs,SRSCtl_CSS_HI,SRSCtl_CSS_LO,ESS);
- tc->setMiscRegNoEffect(ArmISA::SRSCtl,srs);
- //tc->setShadowSet(ESS);
- }
-
- // set EXL bit (don't care if it is already set!)
- replaceBits(stat,Status_EXL_HI,Status_EXL_LO,1);
- tc->setMiscRegNoEffect(ArmISA::Status,stat);
-
- // write EPC
- // warn("Set EPC to %x\n",tc->readPC());
- // CHECK ME or FIXME or FIX ME or POSSIBLE HACK
- // Check to see if the exception occurred in the branch delay slot
- DPRINTF(Arm,"PC: %x, NextPC: %x, NNPC: %x\n",tc->readPC(),tc->readNextPC(),tc->readNextNPC());
- int C_BD=0;
- if(tc->readPC() + sizeof(MachInst) != tc->readNextPC()){
- tc->setMiscRegNoEffect(ArmISA::EPC,tc->readPC()-sizeof(MachInst));
- // In the branch delay slot? set CAUSE_31
- C_BD = 1;
- } else {
- tc->setMiscRegNoEffect(ArmISA::EPC,tc->readPC());
- // In the branch delay slot? reset CAUSE_31
- C_BD = 0;
- }
-
- // Set Cause_EXCCODE field
- MiscReg cause = tc->readMiscReg(ArmISA::Cause);
- replaceBits(cause,Cause_EXCCODE_HI,Cause_EXCCODE_LO,ExcCode);
- replaceBits(cause,Cause_BD_HI,Cause_BD_LO,C_BD);
- replaceBits(cause,Cause_CE_HI,Cause_CE_LO,0);
- tc->setMiscRegNoEffect(ArmISA::Cause,cause);
-
-}
-
-void ArithmeticFault::invoke(ThreadContext *tc)
-{
- DPRINTF(Arm,"%s encountered.\n", name());
- setExceptionState(tc,0xC);
-
- // Set new PC
- Addr HandlerBase;
- MiscReg stat = tc->readMiscReg(ArmISA::Status);
- // Here, the handler is dependent on BEV, which is not modified by setExceptionState()
- if(bits(stat,Status_BEV)==0){ // See MIPS ARM Vol 3, Revision 2, Page 38
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase);
- }else{
- HandlerBase = 0xBFC00200;
- }
- setHandlerPC(HandlerBase,tc);
- // warn("Exception Handler At: %x \n",HandlerBase);
-}
-
-void StoreAddressErrorFault::invoke(ThreadContext *tc)
-{
- DPRINTF(Arm,"%s encountered.\n", name());
- setExceptionState(tc,0x5);
- tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
-
- // Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- setHandlerPC(HandlerBase,tc);
- // warn("Exception Handler At: %x \n",HandlerBase);
- // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
-
-}
-
-void TrapFault::invoke(ThreadContext *tc)
-{
- DPRINTF(Arm,"%s encountered.\n", name());
- // warn("%s encountered.\n", name());
- setExceptionState(tc,0xD);
-
- // Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- setHandlerPC(HandlerBase,tc);
- // warn("Exception Handler At: %x \n",HandlerBase);
- // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
-}
-
-void BreakpointFault::invoke(ThreadContext *tc)
-{
- setExceptionState(tc,0x9);
-
- // Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- setHandlerPC(HandlerBase,tc);
- // warn("Exception Handler At: %x \n",HandlerBase);
- // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
-
-}
-
-void DtbInvalidFault::invoke(ThreadContext *tc)
+Addr
+ArmFaultBase::getVector(ThreadContext *tc)
{
- DPRINTF(Arm,"%s encountered.\n", name());
- // warn("%s encountered.\n", name());
- tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
- MiscReg eh = tc->readMiscReg(ArmISA::EntryHi);
- replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
- replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
- replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
- tc->setMiscRegNoEffect(ArmISA::EntryHi,eh);
- MiscReg ctxt = tc->readMiscReg(ArmISA::Context);
- replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
- tc->setMiscRegNoEffect(ArmISA::Context,ctxt);
- setExceptionState(tc,0x3);
+ // ARM ARM B1-3
+ SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
+
+ // panic if SCTLR.VE because I have no idea what to do with vectored
+ // interrupts
+ assert(!sctlr.ve);
+
+ if (!sctlr.v)
+ return offset();
+ return offset() + HighVecs;
- // Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- setHandlerPC(HandlerBase,tc);
- // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
}
-void AddressErrorFault::invoke(ThreadContext *tc)
-{
- DPRINTF(Arm,"%s encountered.\n", name());
- setExceptionState(tc,0x4);
- tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
-
- // Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- setHandlerPC(HandlerBase,tc);
-}
-
-void ItbInvalidFault::invoke(ThreadContext *tc)
-{
- DPRINTF(Arm,"%s encountered.\n", name());
- setExceptionState(tc,0x2);
- tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
- MiscReg eh = tc->readMiscReg(ArmISA::EntryHi);
- replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
- replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
- replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
- tc->setMiscRegNoEffect(ArmISA::EntryHi,eh);
- MiscReg ctxt = tc->readMiscReg(ArmISA::Context);
- replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
- tc->setMiscRegNoEffect(ArmISA::Context,ctxt);
-
-
- // Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- setHandlerPC(HandlerBase,tc);
- DPRINTF(Arm,"Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
-}
-
-void ItbRefillFault::invoke(ThreadContext *tc)
-{
- DPRINTF(Arm,"%s encountered (%x).\n", name(),BadVAddr);
- Addr HandlerBase;
- tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
- MiscReg eh = tc->readMiscReg(ArmISA::EntryHi);
- replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
- replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
- replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
- tc->setMiscRegNoEffect(ArmISA::EntryHi,eh);
- MiscReg ctxt = tc->readMiscReg(ArmISA::Context);
- replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
- tc->setMiscRegNoEffect(ArmISA::Context,ctxt);
-
- MiscReg stat = tc->readMiscReg(ArmISA::Status);
- // Since handler depends on EXL bit, must check EXL bit before setting it!!
- if(bits(stat,Status_EXL)==1){ // See MIPS ARM Vol 3, Revision 2, Page 38
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- }else{
- HandlerBase = tc->readMiscReg(ArmISA::EBase); // Offset 0x000
- }
-
- setExceptionState(tc,0x2);
- setHandlerPC(HandlerBase,tc);
-}
-
-void DtbRefillFault::invoke(ThreadContext *tc)
-{
- // Set new PC
- DPRINTF(Arm,"%s encountered.\n", name());
- Addr HandlerBase;
- tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
- MiscReg eh = tc->readMiscReg(ArmISA::EntryHi);
- replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
- replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
- replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
- tc->setMiscRegNoEffect(ArmISA::EntryHi,eh);
- MiscReg ctxt = tc->readMiscReg(ArmISA::Context);
- replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
- tc->setMiscRegNoEffect(ArmISA::Context,ctxt);
-
- MiscReg stat = tc->readMiscReg(ArmISA::Status);
- // Since handler depends on EXL bit, must check EXL bit before setting it!!
- if(bits(stat,Status_EXL)==1){ // See MIPS ARM Vol 3, Revision 2, Page 38
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- }else{
- HandlerBase = tc->readMiscReg(ArmISA::EBase); // Offset 0x000
- }
-
-
- setExceptionState(tc,0x3);
-
- setHandlerPC(HandlerBase,tc);
-}
-
-void TLBModifiedFault::invoke(ThreadContext *tc)
-{
- DPRINTF(Arm,"%s encountered.\n", name());
- tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr);
- MiscReg eh = tc->readMiscReg(ArmISA::EntryHi);
- replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid);
- replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2);
- replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X);
- tc->setMiscRegNoEffect(ArmISA::EntryHi,eh);
- MiscReg ctxt = tc->readMiscReg(ArmISA::Context);
- replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2);
- tc->setMiscRegNoEffect(ArmISA::Context,ctxt);
-
- // Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- setExceptionState(tc,0x1);
- setHandlerPC(HandlerBase,tc);
- // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
-
-}
-
-void SystemCallFault::invoke(ThreadContext *tc)
-{
- DPRINTF(Arm,"%s encountered.\n", name());
- setExceptionState(tc,0x8);
-
- // Set new PC
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- setHandlerPC(HandlerBase,tc);
- // warn("Exception Handler At: %x \n",HandlerBase);
- // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC));
-
-}
-
-void InterruptFault::invoke(ThreadContext *tc)
-{
-#if FULL_SYSTEM
- DPRINTF(Arm,"%s encountered.\n", name());
- setExceptionState(tc,0x0A);
- Addr HandlerBase;
-
-
- uint8_t IV = bits(tc->readMiscRegNoEffect(ArmISA::Cause),Cause_IV);
- if (IV)// Offset 200 for release 2
- HandlerBase= 0x20 + vect() + tc->readMiscRegNoEffect(ArmISA::EBase);
- else//Ofset at 180 for release 1
- HandlerBase= vect() + tc->readMiscRegNoEffect(ArmISA::EBase);
-
- setHandlerPC(HandlerBase,tc);
-#endif
-}
-
-#endif // FULL_SYSTEM
-
-void ResetFault::invoke(ThreadContext *tc)
-{
#if FULL_SYSTEM
- DPRINTF(Arm,"%s encountered.\n", name());
- /* All reset activity must be invoked from here */
- tc->setPC(vect());
- tc->setNextPC(vect()+sizeof(MachInst));
- tc->setNextNPC(vect()+sizeof(MachInst)+sizeof(MachInst));
- DPRINTF(Arm,"(%x) - ResetFault::invoke : PC set to %x",(unsigned)tc,(unsigned)tc->readPC());
-#endif
- // Set Coprocessor 1 (Floating Point) To Usable
- //tc->setMiscReg(ArmISA::Status, ArmISA::Status | 0x20000000);
-}
-
-void ReservedInstructionFault::invoke(ThreadContext *tc)
-{
-#if FULL_SYSTEM
- DPRINTF(Arm,"%s encountered.\n", name());
- setExceptionState(tc,0x0A);
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscRegNoEffect(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- setHandlerPC(HandlerBase,tc);
-#else
- panic("%s encountered.\n", name());
-#endif
-}
-
-void ThreadFault::invoke(ThreadContext *tc)
-{
- DPRINTF(Arm,"%s encountered.\n", name());
- panic("%s encountered.\n", name());
-}
-
-void DspStateDisabledFault::invoke(ThreadContext *tc)
-{
- DPRINTF(Arm,"%s encountered.\n", name());
- panic("%s encountered.\n", name());
+void
+ArmFaultBase::invoke(ThreadContext *tc)
+{
+ // ARM ARM B1.6.3
+ FaultBase::invoke(tc);
+ countStat()++;
+
+ SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
+ CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
+ CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR) |
+ tc->readIntReg(INTREG_CONDCODES);
+
+
+ cpsr.mode = nextMode();
+ cpsr.it1 = cpsr.it2 = 0;
+ cpsr.j = 0;
+
+ if (sctlr.te)
+ cpsr.t = 1;
+ cpsr.a = cpsr.a | abortDisable();
+ cpsr.f = cpsr.f | fiqDisable();
+ cpsr.i = 1;
+ tc->setMiscReg(MISCREG_CPSR, cpsr);
+ tc->setIntReg(INTREG_LR, tc->readPC() +
+ (saved_cpsr.t ? thumbPcOffset() : armPcOffset()));
+
+ switch (nextMode()) {
+ case MODE_FIQ:
+ tc->setMiscReg(MISCREG_SPSR_FIQ, saved_cpsr);
+ break;
+ case MODE_IRQ:
+ tc->setMiscReg(MISCREG_SPSR_IRQ, saved_cpsr);
+ break;
+ case MODE_SVC:
+ tc->setMiscReg(MISCREG_SPSR_SVC, saved_cpsr);
+ break;
+ case MODE_UNDEFINED:
+ tc->setMiscReg(MISCREG_SPSR_UND, saved_cpsr);
+ break;
+ case MODE_ABORT:
+ tc->setMiscReg(MISCREG_SPSR_ABT, saved_cpsr);
+ break;
+ default:
+ panic("unknown Mode\n");
+ }
+
+ DPRINTF(Faults, "Invoking Fault: %s cpsr: %#x PC: %#x lr: %#x\n", name(), cpsr,
+ tc->readPC(), tc->readIntReg(INTREG_LR));
+ tc->setPC(getVector(tc));
+ tc->setNextPC(getVector(tc) + cpsr.t ? 2 : 4 );
}
+#endif // FULL_SYSTEM
-void CoprocessorUnusableFault::invoke(ThreadContext *tc)
-{
-#if FULL_SYSTEM
- DPRINTF(Arm,"%s encountered.\n", name());
- setExceptionState(tc,0xb);
- /* The ID of the coprocessor causing the exception is stored in CoprocessorUnusableFault::coProcID */
- MiscReg cause = tc->readMiscReg(ArmISA::Cause);
- replaceBits(cause,Cause_CE_HI,Cause_CE_LO,coProcID);
- tc->setMiscRegNoEffect(ArmISA::Cause,cause);
+// return via SUBS pc, lr, xxx; rfe, movs, ldm
- Addr HandlerBase;
- HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector
- setHandlerPC(HandlerBase,tc);
- // warn("Status: %x, Cause: %x\n",tc->readMiscReg(ArmISA::Status),tc->readMiscReg(ArmISA::Cause));
-#else
- warn("%s (CP%d) encountered.\n", name(), coProcID);
-#endif
-}
} // namespace ArmISA
diff --git a/src/arch/arm/faults.hh b/src/arch/arm/faults.hh
index 28ecd7591..7f8aa66b6 100644
--- a/src/arch/arm/faults.hh
+++ b/src/arch/arm/faults.hh
@@ -26,548 +26,79 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * Authors: Gabe Black
- * Stephen Hines
+ * Authors: Ali Saidi
+ * Gabe Black
*/
#ifndef __ARM_FAULTS_HH__
#define __ARM_FAULTS_HH__
+#include "arch/arm/types.hh"
+#include "config/full_system.hh"
#include "sim/faults.hh"
// The design of the "name" and "vect" functions is in sim/faults.hh
namespace ArmISA
{
-typedef const Addr FaultVect;
+typedef const Addr FaultOffset;
-class ArmFault : public FaultBase
+class ArmFaultBase : public FaultBase
{
protected:
- virtual bool skipFaultingInstruction() {return false;}
- virtual bool setRestartAddress() {return true;}
- public:
- Addr BadVAddr;
- Addr EntryHi_Asid;
- Addr EntryHi_VPN2;
- Addr EntryHi_VPN2X;
- Addr Context_BadVPN2;
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc) {};
- void setExceptionState(ThreadContext *,uint8_t);
- void setHandlerPC(Addr,ThreadContext *);
-#endif
- virtual FaultVect vect() = 0;
- virtual FaultStat & countStat() = 0;
-};
-
-class MachineCheckFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- bool isMachineCheckFault() {return true;}
-};
-
-class NonMaskableInterrupt : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- bool isNonMaskableInterrupt() {return true;}
-};
-
-class AlignmentFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- bool isAlignmentFault() {return true;}
-};
-
-class AddressErrorFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-
-};
-class StoreAddressErrorFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-
-};
-class UnimplementedOpcodeFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-};
-
-
-class TLBRefillIFetchFault : public ArmFault
-{
- private:
- Addr vaddr;
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
-class TLBInvalidIFetchFault : public ArmFault
-{
- private:
- Addr vaddr;
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
-
-class NDtbMissFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-};
-
-class PDtbMissFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-};
-
-class DtbPageFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-};
-
-class DtbAcvFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-};
-
-class CacheErrorFault : public ArmFault
-{
- private:
- Addr vaddr;
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
-
-
-
-
-static inline Fault genMachineCheckFault()
-{
- return new MachineCheckFault;
-}
-
-static inline Fault genAlignmentFault()
-{
- return new AlignmentFault;
-}
-
-class ResetFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-
-};
-class SystemCallFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
-
-class SoftResetFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
-class DebugSingleStep : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
-class DebugInterrupt : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
-
-class CoprocessorUnusableFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- int coProcID;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
- CoprocessorUnusableFault(int _procid){ coProcID = _procid;}
-};
+ Addr getVector(ThreadContext *tc);
-class ReservedInstructionFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
-
-class ThreadFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
+ struct FaultVals
+ {
+ const FaultName name;
+ const FaultOffset offset;
+ const OperatingMode nextMode;
+ const uint8_t armPcOffset;
+ const uint8_t thumbPcOffset;
+ const bool abortDisable;
+ const bool fiqDisable;
+ FaultStat count;
+ };
-
-class ArithmeticFault : public ArmFault
-{
- protected:
- bool skipFaultingInstruction() {return true;}
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
+ void invoke(ThreadContext *tc);
#endif
+ virtual FaultStat& countStat() = 0;
+ virtual FaultOffset offset() = 0;
+ virtual OperatingMode nextMode() = 0;
+ virtual uint8_t armPcOffset() = 0;
+ virtual uint8_t thumbPcOffset() = 0;
+ virtual bool abortDisable() = 0;
+ virtual bool fiqDisable() = 0;
};
-class InterruptFault : public ArmFault
+template<typename T>
+class ArmFault : public ArmFaultBase
{
protected:
- bool setRestartAddress() {return false;}
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-
- //void invoke(ThreadContext * tc);
-};
-
-class TrapFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-};
-
-class BreakpointFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-};
-
-class ItbRefillFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-};
-class DtbRefillFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-};
-
-class ItbPageFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-};
-
-class ItbInvalidFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-
-};
-class TLBModifiedFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-
-};
+ static FaultVals vals;
-class DtbInvalidFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-
+ FaultName name() const { return vals.name; }
+ FaultStat & countStat() {return vals.count;}
+ FaultOffset offset() { return vals.offset; }
+ OperatingMode nextMode() { return vals.nextMode; }
+ uint8_t armPcOffset() { return vals.armPcOffset; }
+ uint8_t thumbPcOffset() { return vals.thumbPcOffset; }
+ bool abortDisable() { return vals.abortDisable; }
+ bool fiqDisable() { return vals.fiqDisable; }
};
-class FloatEnableFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-};
-class ItbMissFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-};
+class Reset : public ArmFault<Reset> {};
+class UndefinedInstruction : public ArmFault<UndefinedInstruction> {};
+class SupervisorCall : public ArmFault<SupervisorCall> {};
+class PrefetchAbort : public ArmFault<PrefetchAbort> {};
+class DataAbort : public ArmFault<DataAbort> {};
+class Interrupt : public ArmFault<Interrupt> {};
+class FastInterrupt : public ArmFault<FastInterrupt> {};
-class ItbAcvFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-};
-
-class IntegerOverflowFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-};
-
-class DspStateDisabledFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
} // ArmISA namespace
diff --git a/src/arch/arm/insts/macromem.hh b/src/arch/arm/insts/macromem.hh
index 541c9e3f5..714b8bb7e 100644
--- a/src/arch/arm/insts/macromem.hh
+++ b/src/arch/arm/insts/macromem.hh
@@ -84,33 +84,20 @@ class MicroMemOp : public MicroIntOp
*/
class ArmMacroMemoryOp : public PredMacroOp
{
- protected:
+ protected:
/// Memory request flags. See mem_req_base.hh.
unsigned memAccessFlags;
uint32_t reglist;
uint32_t ones;
- uint32_t puswl,
- prepost,
- up,
- psruser,
- writeback,
- loadop;
ArmMacroMemoryOp(const char *mnem, ExtMachInst _machInst,
OpClass __opClass)
- : PredMacroOp(mnem, _machInst, __opClass),
- memAccessFlags(0),
- reglist(machInst.regList), ones(0),
- puswl(machInst.puswl),
- prepost(machInst.puswl.prepost),
- up(machInst.puswl.up),
- psruser(machInst.puswl.psruser),
- writeback(machInst.puswl.writeback),
- loadop(machInst.puswl.loadOp)
+ : PredMacroOp(mnem, _machInst, __opClass), memAccessFlags(0),
+ reglist(machInst.regList), ones(0)
{
ones = number_of_ones(reglist);
- numMicroops = ones + writeback + 1;
+ numMicroops = ones + machInst.puswl.writeback + 1;
// Remember that writeback adds a uop
microOps = new StaticInstPtr[numMicroops];
}
@@ -121,7 +108,7 @@ class ArmMacroMemoryOp : public PredMacroOp
*/
class ArmMacroFPAOp : public PredMacroOp
{
- protected:
+ protected:
uint32_t puswl,
prepost,
up,
@@ -150,7 +137,7 @@ class ArmMacroFPAOp : public PredMacroOp
*/
class ArmMacroFMOp : public PredMacroOp
{
- protected:
+ protected:
uint32_t punwl,
prepost,
up,
diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc
index df2d5de25..bf7a38c58 100644
--- a/src/arch/arm/insts/static_inst.cc
+++ b/src/arch/arm/insts/static_inst.cc
@@ -27,8 +27,10 @@
* Authors: Stephen Hines
*/
+#include "arch/arm/faults.hh"
#include "arch/arm/insts/static_inst.hh"
#include "base/condcodes.hh"
+#include "base/cprintf.hh"
#include "base/loader/symtab.hh"
namespace ArmISA
@@ -62,7 +64,7 @@ ArmStaticInst::shift_rm_imm(uint32_t base, uint32_t shamt,
else
return (base << (32 - shamt)) | (base >> shamt);
default:
- fprintf(stderr, "Unhandled shift type\n");
+ ccprintf(std::cerr, "Unhandled shift type\n");
exit(1);
break;
}
@@ -101,7 +103,7 @@ ArmStaticInst::shift_rm_rs(uint32_t base, uint32_t shamt,
else
return (base << (32 - shamt)) | (base >> shamt);
default:
- fprintf(stderr, "Unhandled shift type\n");
+ ccprintf(std::cerr, "Unhandled shift type\n");
exit(1);
break;
}
@@ -141,7 +143,7 @@ ArmStaticInst::shift_carry_imm(uint32_t base, uint32_t shamt,
else
return (base >> (shamt - 1)) & 1;
default:
- fprintf(stderr, "Unhandled shift type\n");
+ ccprintf(std::cerr, "Unhandled shift type\n");
exit(1);
break;
}
@@ -182,7 +184,7 @@ ArmStaticInst::shift_carry_rs(uint32_t base, uint32_t shamt,
shamt = 32;
return (base >> (shamt - 1)) & 1;
default:
- fprintf(stderr, "Unhandled shift type\n");
+ ccprintf(std::cerr, "Unhandled shift type\n");
exit(1);
break;
}
diff --git a/src/arch/arm/insts/static_inst.hh b/src/arch/arm/insts/static_inst.hh
index c963c1827..f2881c3b6 100644
--- a/src/arch/arm/insts/static_inst.hh
+++ b/src/arch/arm/insts/static_inst.hh
@@ -74,6 +74,56 @@ class ArmStaticInst : public StaticInst
void printDataInst(std::ostream &os, bool withImm) const;
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+
+ static uint32_t
+ cpsrWriteByInstr(CPSR cpsr, uint32_t val,
+ uint8_t byteMask, bool affectState)
+ {
+ bool privileged = (cpsr.mode != MODE_USER);
+
+ uint32_t bitMask = 0;
+
+ if (bits(byteMask, 3)) {
+ unsigned lowIdx = affectState ? 24 : 27;
+ bitMask = bitMask | mask(31, lowIdx);
+ }
+ if (bits(byteMask, 2)) {
+ bitMask = bitMask | mask(19, 16);
+ }
+ if (bits(byteMask, 1)) {
+ unsigned highIdx = affectState ? 15 : 9;
+ unsigned lowIdx = privileged ? 8 : 9;
+ bitMask = bitMask | mask(highIdx, lowIdx);
+ }
+ if (bits(byteMask, 0)) {
+ if (privileged) {
+ bitMask = bitMask | mask(7, 6);
+ bitMask = bitMask | mask(5);
+ }
+ if (affectState)
+ bitMask = bitMask | (1 << 5);
+ }
+
+ return ((uint32_t)cpsr & ~bitMask) | (val & bitMask);
+ }
+
+ static uint32_t
+ spsrWriteByInstr(uint32_t spsr, uint32_t val,
+ uint8_t byteMask, bool affectState)
+ {
+ uint32_t bitMask = 0;
+
+ if (bits(byteMask, 3))
+ bitMask = bitMask | mask(31, 24);
+ if (bits(byteMask, 2))
+ bitMask = bitMask | mask(19, 16);
+ if (bits(byteMask, 1))
+ bitMask = bitMask | mask(15, 8);
+ if (bits(byteMask, 0))
+ bitMask = bitMask | mask(7, 0);
+
+ return ((spsr & ~bitMask) | (val & bitMask));
+ }
};
}
diff --git a/src/mem/slicc/ast/AST.cc b/src/arch/arm/interrupts.cc
index e893c453a..a47ebc75d 100644
--- a/src/mem/slicc/ast/AST.cc
+++ b/src/arch/arm/interrupts.cc
@@ -1,6 +1,5 @@
-
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009 ARM Limited
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,15 +24,14 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * AST.C
- *
- * Description: See AST.hh
- *
- * $Id$
*
+ * Authors: Ali Saidi
*/
-#include "mem/slicc/ast/AST.hh"
+#include "arch/arm/interrupts.hh"
+
+ArmISA::Interrupts *
+ArmInterruptsParams::create()
+{
+ return new ArmISA::Interrupts(this);
+}
diff --git a/src/mem/slicc/ast/LiteralExprAST.hh b/src/arch/arm/interrupts.hh
index c895fa9ae..189341d6b 100644
--- a/src/mem/slicc/ast/LiteralExprAST.hh
+++ b/src/arch/arm/interrupts.hh
@@ -1,6 +1,6 @@
-
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * Copyright (c) 2009 ARM Limited
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,59 +25,97 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * LiteralExprAST.hh
- *
- * Description:
- *
- * $Id: LiteralExprAST.hh,v 3.1 2001/12/12 01:00:20 milo Exp $
*
+ * Authors: Ali Saidi
*/
-#ifndef LITERALEXPRAST_H
-#define LITERALEXPRAST_H
+#ifndef __ARCH_ARM_INTERRUPT_HH__
+#define __ARCH_ARM_INTERRUPT_HH__
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/ExprAST.hh"
+#include "arch/arm/faults.hh"
+#include "arch/arm/isa_traits.hh"
+#include "arch/arm/registers.hh"
+#include "cpu/thread_context.hh"
+#include "params/ArmInterrupts.hh"
+#include "sim/sim_object.hh"
+namespace ArmISA
+{
-class LiteralExprAST : public ExprAST {
-public:
- // Constructors
- LiteralExprAST(string* lit_ptr, string type) : ExprAST() { m_lit_ptr = lit_ptr; m_type = type; }
+class Interrupts : public SimObject
+{
+ private:
+ BaseCPU * cpu;
- // Destructor
- ~LiteralExprAST() { delete m_lit_ptr; }
+ uint64_t intStatus;
- // Public Methods
- Type* generate(string& code) const;
- void print(ostream& out) const { out << "[Literal: " << *m_lit_ptr << "]"; }
-private:
- // Private Methods
+ public:
- // Private copy constructor and assignment operator
- LiteralExprAST(const LiteralExprAST& obj);
- LiteralExprAST& operator=(const LiteralExprAST& obj);
+ void
+ setCPU(BaseCPU * _cpu)
+ {
+ cpu = _cpu;
+ }
- // Data Members (m_ prefix)
- string* m_lit_ptr;
- string m_type;
-};
+ typedef ArmInterruptsParams Params;
-// Output operator declaration
-ostream& operator<<(ostream& out, const LiteralExprAST& obj);
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
-// ******************* Definitions *******************
+ Interrupts(Params * p) : SimObject(p), cpu(NULL)
+ {
+ clearAll();
+ }
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const LiteralExprAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-#endif //LITERALEXPRAST_H
+ void
+ post(int int_num, int index)
+ {
+ }
+
+ void
+ clear(int int_num, int index)
+ {
+ }
+
+ void
+ clearAll()
+ {
+ intStatus = 0;
+ }
+
+ bool
+ checkInterrupts(ThreadContext *tc) const
+ {
+ return intStatus;
+ }
+
+ Fault
+ getInterrupt(ThreadContext *tc)
+ {
+ warn_once("ARM Interrupts not handled\n");
+ return NoFault;
+ }
+
+ void
+ updateIntrInfo(ThreadContext *tc)
+ {
+
+ }
+
+ void
+ serialize(std::ostream &os)
+ {
+ }
+
+ void
+ unserialize(Checkpoint *cp, const std::string &section)
+ {
+ }
+};
+} // namespace ARM_ISA
+
+#endif // __ARCH_ARM_INTERRUPT_HH__
diff --git a/src/arch/arm/intregs.hh b/src/arch/arm/intregs.hh
new file mode 100644
index 000000000..15499601a
--- /dev/null
+++ b/src/arch/arm/intregs.hh
@@ -0,0 +1,337 @@
+/*
+ * Copyright (c) 2009 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#include <assert.h>
+
+#ifndef __ARCH_ARM_INTREGS_HH__
+#define __ARCH_ARM_INTREGS_HH__
+
+namespace ArmISA
+{
+
+enum IntRegIndex
+{
+ /* All the unique register indices. */
+ INTREG_R0,
+ INTREG_R1,
+ INTREG_R2,
+ INTREG_R3,
+ INTREG_R4,
+ INTREG_R5,
+ INTREG_R6,
+ INTREG_R7,
+ INTREG_R8,
+ INTREG_R9,
+ INTREG_R10,
+ INTREG_R11,
+ INTREG_R12,
+ INTREG_R13,
+ INTREG_SP = INTREG_R13,
+ INTREG_R14,
+ INTREG_LR = INTREG_R14,
+ INTREG_R15,
+ INTREG_PC = INTREG_R15,
+
+ INTREG_R13_SVC,
+ INTREG_SP_SVC = INTREG_R13_SVC,
+ INTREG_R14_SVC,
+ INTREG_LR_SVC = INTREG_R14_SVC,
+
+ INTREG_R13_MON,
+ INTREG_SP_MON = INTREG_R13_MON,
+ INTREG_R14_MON,
+ INTREG_LR_MON = INTREG_R14_MON,
+
+ INTREG_R13_ABT,
+ INTREG_SP_ABT = INTREG_R13_ABT,
+ INTREG_R14_ABT,
+ INTREG_LR_ABT = INTREG_R14_ABT,
+
+ INTREG_R13_UND,
+ INTREG_SP_UND = INTREG_R13_UND,
+ INTREG_R14_UND,
+ INTREG_LR_UND = INTREG_R14_UND,
+
+ INTREG_R13_IRQ,
+ INTREG_SP_IRQ = INTREG_R13_IRQ,
+ INTREG_R14_IRQ,
+ INTREG_LR_IRQ = INTREG_R14_IRQ,
+
+ INTREG_R8_FIQ,
+ INTREG_R9_FIQ,
+ INTREG_R10_FIQ,
+ INTREG_R11_FIQ,
+ INTREG_R12_FIQ,
+ INTREG_R13_FIQ,
+ INTREG_SP_FIQ = INTREG_R13_FIQ,
+ INTREG_R14_FIQ,
+ INTREG_LR_FIQ = INTREG_R14_FIQ,
+
+ INTREG_ZERO, // Dummy zero reg since there has to be one.
+ INTREG_UREG0,
+ INTREG_RHI,
+ INTREG_RLO,
+ INTREG_CONDCODES,
+
+ NUM_INTREGS,
+ NUM_ARCH_INTREGS = INTREG_PC + 1,
+
+ /* All the aliased indexes. */
+
+ /* USR mode */
+ INTREG_R0_USR = INTREG_R0,
+ INTREG_R1_USR = INTREG_R1,
+ INTREG_R2_USR = INTREG_R2,
+ INTREG_R3_USR = INTREG_R3,
+ INTREG_R4_USR = INTREG_R4,
+ INTREG_R5_USR = INTREG_R5,
+ INTREG_R6_USR = INTREG_R6,
+ INTREG_R7_USR = INTREG_R7,
+ INTREG_R8_USR = INTREG_R8,
+ INTREG_R9_USR = INTREG_R9,
+ INTREG_R10_USR = INTREG_R10,
+ INTREG_R11_USR = INTREG_R11,
+ INTREG_R12_USR = INTREG_R12,
+ INTREG_R13_USR = INTREG_R13,
+ INTREG_SP_USR = INTREG_SP,
+ INTREG_R14_USR = INTREG_R14,
+ INTREG_LR_USR = INTREG_LR,
+ INTREG_R15_USR = INTREG_R15,
+ INTREG_PC_USR = INTREG_PC,
+
+ /* SVC mode */
+ INTREG_R0_SVC = INTREG_R0,
+ INTREG_R1_SVC = INTREG_R1,
+ INTREG_R2_SVC = INTREG_R2,
+ INTREG_R3_SVC = INTREG_R3,
+ INTREG_R4_SVC = INTREG_R4,
+ INTREG_R5_SVC = INTREG_R5,
+ INTREG_R6_SVC = INTREG_R6,
+ INTREG_R7_SVC = INTREG_R7,
+ INTREG_R8_SVC = INTREG_R8,
+ INTREG_R9_SVC = INTREG_R9,
+ INTREG_R10_SVC = INTREG_R10,
+ INTREG_R11_SVC = INTREG_R11,
+ INTREG_R12_SVC = INTREG_R12,
+ INTREG_PC_SVC = INTREG_PC,
+ INTREG_R15_SVC = INTREG_R15,
+
+ /* MON mode */
+ INTREG_R0_MON = INTREG_R0,
+ INTREG_R1_MON = INTREG_R1,
+ INTREG_R2_MON = INTREG_R2,
+ INTREG_R3_MON = INTREG_R3,
+ INTREG_R4_MON = INTREG_R4,
+ INTREG_R5_MON = INTREG_R5,
+ INTREG_R6_MON = INTREG_R6,
+ INTREG_R7_MON = INTREG_R7,
+ INTREG_R8_MON = INTREG_R8,
+ INTREG_R9_MON = INTREG_R9,
+ INTREG_R10_MON = INTREG_R10,
+ INTREG_R11_MON = INTREG_R11,
+ INTREG_R12_MON = INTREG_R12,
+ INTREG_PC_MON = INTREG_PC,
+ INTREG_R15_MON = INTREG_R15,
+
+ /* ABT mode */
+ INTREG_R0_ABT = INTREG_R0,
+ INTREG_R1_ABT = INTREG_R1,
+ INTREG_R2_ABT = INTREG_R2,
+ INTREG_R3_ABT = INTREG_R3,
+ INTREG_R4_ABT = INTREG_R4,
+ INTREG_R5_ABT = INTREG_R5,
+ INTREG_R6_ABT = INTREG_R6,
+ INTREG_R7_ABT = INTREG_R7,
+ INTREG_R8_ABT = INTREG_R8,
+ INTREG_R9_ABT = INTREG_R9,
+ INTREG_R10_ABT = INTREG_R10,
+ INTREG_R11_ABT = INTREG_R11,
+ INTREG_R12_ABT = INTREG_R12,
+ INTREG_PC_ABT = INTREG_PC,
+ INTREG_R15_ABT = INTREG_R15,
+
+ /* UND mode */
+ INTREG_R0_UND = INTREG_R0,
+ INTREG_R1_UND = INTREG_R1,
+ INTREG_R2_UND = INTREG_R2,
+ INTREG_R3_UND = INTREG_R3,
+ INTREG_R4_UND = INTREG_R4,
+ INTREG_R5_UND = INTREG_R5,
+ INTREG_R6_UND = INTREG_R6,
+ INTREG_R7_UND = INTREG_R7,
+ INTREG_R8_UND = INTREG_R8,
+ INTREG_R9_UND = INTREG_R9,
+ INTREG_R10_UND = INTREG_R10,
+ INTREG_R11_UND = INTREG_R11,
+ INTREG_R12_UND = INTREG_R12,
+ INTREG_PC_UND = INTREG_PC,
+ INTREG_R15_UND = INTREG_R15,
+
+ /* IRQ mode */
+ INTREG_R0_IRQ = INTREG_R0,
+ INTREG_R1_IRQ = INTREG_R1,
+ INTREG_R2_IRQ = INTREG_R2,
+ INTREG_R3_IRQ = INTREG_R3,
+ INTREG_R4_IRQ = INTREG_R4,
+ INTREG_R5_IRQ = INTREG_R5,
+ INTREG_R6_IRQ = INTREG_R6,
+ INTREG_R7_IRQ = INTREG_R7,
+ INTREG_R8_IRQ = INTREG_R8,
+ INTREG_R9_IRQ = INTREG_R9,
+ INTREG_R10_IRQ = INTREG_R10,
+ INTREG_R11_IRQ = INTREG_R11,
+ INTREG_R12_IRQ = INTREG_R12,
+ INTREG_PC_IRQ = INTREG_PC,
+ INTREG_R15_IRQ = INTREG_R15,
+
+ /* FIQ mode */
+ INTREG_R0_FIQ = INTREG_R0,
+ INTREG_R1_FIQ = INTREG_R1,
+ INTREG_R2_FIQ = INTREG_R2,
+ INTREG_R3_FIQ = INTREG_R3,
+ INTREG_R4_FIQ = INTREG_R4,
+ INTREG_R5_FIQ = INTREG_R5,
+ INTREG_R6_FIQ = INTREG_R6,
+ INTREG_R7_FIQ = INTREG_R7,
+ INTREG_PC_FIQ = INTREG_PC,
+ INTREG_R15_FIQ = INTREG_R15,
+};
+
+typedef IntRegIndex IntRegMap[NUM_ARCH_INTREGS];
+
+const IntRegMap IntRegUsrMap = {
+ INTREG_R0_USR, INTREG_R1_USR, INTREG_R2_USR, INTREG_R3_USR,
+ INTREG_R4_USR, INTREG_R5_USR, INTREG_R6_USR, INTREG_R7_USR,
+ INTREG_R8_USR, INTREG_R9_USR, INTREG_R10_USR, INTREG_R11_USR,
+ INTREG_R12_USR, INTREG_R13_USR, INTREG_R14_USR, INTREG_R15_USR
+};
+
+static inline IntRegIndex
+INTREG_USR(unsigned index)
+{
+ assert(index < NUM_ARCH_INTREGS);
+ return IntRegUsrMap[index];
+}
+
+const IntRegMap IntRegSvcMap = {
+ INTREG_R0_SVC, INTREG_R1_SVC, INTREG_R2_SVC, INTREG_R3_SVC,
+ INTREG_R4_SVC, INTREG_R5_SVC, INTREG_R6_SVC, INTREG_R7_SVC,
+ INTREG_R8_SVC, INTREG_R9_SVC, INTREG_R10_SVC, INTREG_R11_SVC,
+ INTREG_R12_SVC, INTREG_R13_SVC, INTREG_R14_SVC, INTREG_R15_SVC
+};
+
+static inline IntRegIndex
+INTREG_SVC(unsigned index)
+{
+ assert(index < NUM_ARCH_INTREGS);
+ return IntRegSvcMap[index];
+}
+
+const IntRegMap IntRegMonMap = {
+ INTREG_R0_MON, INTREG_R1_MON, INTREG_R2_MON, INTREG_R3_MON,
+ INTREG_R4_MON, INTREG_R5_MON, INTREG_R6_MON, INTREG_R7_MON,
+ INTREG_R8_MON, INTREG_R9_MON, INTREG_R10_MON, INTREG_R11_MON,
+ INTREG_R12_MON, INTREG_R13_MON, INTREG_R14_MON, INTREG_R15_MON
+};
+
+static inline IntRegIndex
+INTREG_MON(unsigned index)
+{
+ assert(index < NUM_ARCH_INTREGS);
+ return IntRegMonMap[index];
+}
+
+const IntRegMap IntRegAbtMap = {
+ INTREG_R0_ABT, INTREG_R1_ABT, INTREG_R2_ABT, INTREG_R3_ABT,
+ INTREG_R4_ABT, INTREG_R5_ABT, INTREG_R6_ABT, INTREG_R7_ABT,
+ INTREG_R8_ABT, INTREG_R9_ABT, INTREG_R10_ABT, INTREG_R11_ABT,
+ INTREG_R12_ABT, INTREG_R13_ABT, INTREG_R14_ABT, INTREG_R15_ABT
+};
+
+static inline IntRegIndex
+INTREG_ABT(unsigned index)
+{
+ assert(index < NUM_ARCH_INTREGS);
+ return IntRegAbtMap[index];
+}
+
+const IntRegMap IntRegUndMap = {
+ INTREG_R0_UND, INTREG_R1_UND, INTREG_R2_UND, INTREG_R3_UND,
+ INTREG_R4_UND, INTREG_R5_UND, INTREG_R6_UND, INTREG_R7_UND,
+ INTREG_R8_UND, INTREG_R9_UND, INTREG_R10_UND, INTREG_R11_UND,
+ INTREG_R12_UND, INTREG_R13_UND, INTREG_R14_UND, INTREG_R15_UND
+};
+
+static inline IntRegIndex
+INTREG_UND(unsigned index)
+{
+ assert(index < NUM_ARCH_INTREGS);
+ return IntRegUndMap[index];
+}
+
+const IntRegMap IntRegIrqMap = {
+ INTREG_R0_IRQ, INTREG_R1_IRQ, INTREG_R2_IRQ, INTREG_R3_IRQ,
+ INTREG_R4_IRQ, INTREG_R5_IRQ, INTREG_R6_IRQ, INTREG_R7_IRQ,
+ INTREG_R8_IRQ, INTREG_R9_IRQ, INTREG_R10_IRQ, INTREG_R11_IRQ,
+ INTREG_R12_IRQ, INTREG_R13_IRQ, INTREG_R14_IRQ, INTREG_R15_IRQ
+};
+
+static inline IntRegIndex
+INTREG_IRQ(unsigned index)
+{
+ assert(index < NUM_ARCH_INTREGS);
+ return IntRegIrqMap[index];
+}
+
+const IntRegMap IntRegFiqMap = {
+ INTREG_R0_FIQ, INTREG_R1_FIQ, INTREG_R2_FIQ, INTREG_R3_FIQ,
+ INTREG_R4_FIQ, INTREG_R5_FIQ, INTREG_R6_FIQ, INTREG_R7_FIQ,
+ INTREG_R8_FIQ, INTREG_R9_FIQ, INTREG_R10_FIQ, INTREG_R11_FIQ,
+ INTREG_R12_FIQ, INTREG_R13_FIQ, INTREG_R14_FIQ, INTREG_R15_FIQ
+};
+
+static inline IntRegIndex
+INTREG_FIQ(unsigned index)
+{
+ assert(index < NUM_ARCH_INTREGS);
+ return IntRegFiqMap[index];
+}
+
+static inline IntRegIndex
+intRegForceUser(unsigned index)
+{
+ assert(index < NUM_ARCH_INTREGS);
+
+ return index == 15 ? (IntRegIndex)15 : (IntRegIndex)(index + NUM_INTREGS);
+}
+
+}
+
+#endif
diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh
index 2315afa9e..905eb0183 100644
--- a/src/arch/arm/isa.hh
+++ b/src/arch/arm/isa.hh
@@ -44,6 +44,38 @@ namespace ArmISA
{
protected:
MiscReg miscRegs[NumMiscRegs];
+ const IntRegIndex *intRegMap;
+
+ void
+ updateRegMap(CPSR cpsr)
+ {
+ switch (cpsr.mode) {
+ case MODE_USER:
+ case MODE_SYSTEM:
+ intRegMap = IntRegUsrMap;
+ break;
+ case MODE_FIQ:
+ intRegMap = IntRegFiqMap;
+ break;
+ case MODE_IRQ:
+ intRegMap = IntRegIrqMap;
+ break;
+ case MODE_SVC:
+ intRegMap = IntRegSvcMap;
+ break;
+ case MODE_MON:
+ intRegMap = IntRegMonMap;
+ break;
+ case MODE_ABORT:
+ intRegMap = IntRegAbtMap;
+ break;
+ case MODE_UNDEFINED:
+ intRegMap = IntRegUndMap;
+ break;
+ default:
+ panic("Unrecognized mode setting in CPSR.\n");
+ }
+ }
public:
void clear()
@@ -52,6 +84,15 @@ namespace ArmISA
CPSR cpsr = 0;
cpsr.mode = MODE_USER;
miscRegs[MISCREG_CPSR] = cpsr;
+ updateRegMap(cpsr);
+
+ SCTLR sctlr = 0;
+ sctlr.nmfi = 1;
+ sctlr.rao1 = 1;
+ sctlr.rao2 = 1;
+ sctlr.rao3 = 1;
+ sctlr.rao4 = 1;
+
//XXX We need to initialize the rest of the state.
}
@@ -59,34 +100,94 @@ namespace ArmISA
readMiscRegNoEffect(int misc_reg)
{
assert(misc_reg < NumMiscRegs);
+ if (misc_reg == MISCREG_SPSR) {
+ CPSR cpsr = miscRegs[MISCREG_CPSR];
+ switch (cpsr.mode) {
+ case MODE_USER:
+ return miscRegs[MISCREG_SPSR];
+ case MODE_FIQ:
+ return miscRegs[MISCREG_SPSR_FIQ];
+ case MODE_IRQ:
+ return miscRegs[MISCREG_SPSR_IRQ];
+ case MODE_SVC:
+ return miscRegs[MISCREG_SPSR_SVC];
+ case MODE_MON:
+ return miscRegs[MISCREG_SPSR_MON];
+ case MODE_ABORT:
+ return miscRegs[MISCREG_SPSR_ABT];
+ case MODE_UNDEFINED:
+ return miscRegs[MISCREG_SPSR_UND];
+ default:
+ return miscRegs[MISCREG_SPSR];
+ }
+ }
return miscRegs[misc_reg];
}
MiscReg
readMiscReg(int misc_reg, ThreadContext *tc)
{
- assert(misc_reg < NumMiscRegs);
- return miscRegs[misc_reg];
+ return readMiscRegNoEffect(misc_reg);
}
void
setMiscRegNoEffect(int misc_reg, const MiscReg &val)
{
assert(misc_reg < NumMiscRegs);
+ if (misc_reg == MISCREG_SPSR) {
+ CPSR cpsr = miscRegs[MISCREG_CPSR];
+ switch (cpsr.mode) {
+ case MODE_USER:
+ miscRegs[MISCREG_SPSR] = val;
+ return;
+ case MODE_FIQ:
+ miscRegs[MISCREG_SPSR_FIQ] = val;
+ return;
+ case MODE_IRQ:
+ miscRegs[MISCREG_SPSR_IRQ] = val;
+ return;
+ case MODE_SVC:
+ miscRegs[MISCREG_SPSR_SVC] = val;
+ return;
+ case MODE_MON:
+ miscRegs[MISCREG_SPSR_MON] = val;
+ return;
+ case MODE_ABORT:
+ miscRegs[MISCREG_SPSR_ABT] = val;
+ return;
+ case MODE_UNDEFINED:
+ miscRegs[MISCREG_SPSR_UND] = val;
+ return;
+ default:
+ miscRegs[MISCREG_SPSR] = val;
+ return;
+ }
+ }
miscRegs[misc_reg] = val;
}
void
setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
{
- assert(misc_reg < NumMiscRegs);
- miscRegs[misc_reg] = val;
+ if (misc_reg == MISCREG_CPSR) {
+ updateRegMap(val);
+ }
+ return setMiscRegNoEffect(misc_reg, val);
}
int
flattenIntIndex(int reg)
{
- return reg;
+ assert(reg >= 0);
+ if (reg < NUM_ARCH_INTREGS) {
+ return intRegMap[reg];
+ } else if (reg < NUM_INTREGS) {
+ return reg;
+ } else {
+ reg -= NUM_INTREGS;
+ assert(reg < NUM_ARCH_INTREGS);
+ return reg;
+ }
}
int
@@ -95,9 +196,10 @@ namespace ArmISA
return reg;
}
- void serialize(std::ostream &os)
+ void serialize(EventManager *em, std::ostream &os)
{}
- void unserialize(Checkpoint *cp, const std::string &section)
+ void unserialize(EventManager *em, Checkpoint *cp,
+ const std::string &section)
{}
ISA()
diff --git a/src/arch/arm/isa/bitfields.isa b/src/arch/arm/isa/bitfields.isa
index 5785939cc..8ff819983 100644
--- a/src/arch/arm/isa/bitfields.isa
+++ b/src/arch/arm/isa/bitfields.isa
@@ -38,14 +38,18 @@ def bitfield ENCODING encoding;
def bitfield OPCODE opcode;
def bitfield MEDIA_OPCODE mediaOpcode;
def bitfield MEDIA_OPCODE2 mediaOpcode2;
+def bitfield USEIMM useImm;
def bitfield OPCODE_24 opcode24;
def bitfield OPCODE_23_20 opcode23_20;
def bitfield OPCODE_23_21 opcode23_21;
def bitfield OPCODE_22 opcode22;
+def bitfield OPCODE_20 opcode20;
def bitfield OPCODE_19 opcode19;
+def bitfield OPCODE_18 opcode18;
def bitfield OPCODE_15_12 opcode15_12;
def bitfield OPCODE_15 opcode15;
def bitfield MISC_OPCODE miscOpcode;
+def bitfield OPC2 opc2;
def bitfield OPCODE_7 opcode7;
def bitfield OPCODE_4 opcode4;
diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa
index a999b52e9..ff20c6107 100644
--- a/src/arch/arm/isa/decoder.isa
+++ b/src/arch/arm/isa/decoder.isa
@@ -51,20 +51,25 @@ format DataOp {
resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
Rd = (uint32_t)(resTemp & 0xffffffff);
Rn = (uint32_t)(resTemp >> 32);
- }});
- 0x5: WarnUnimpl::smlal();
+ }}, llbit);
+ 0x5: smlal({{
+ resTemp = ((int64_t)Rm) * ((int64_t)Rs);
+ resTemp += (((uint64_t)Rn) << 32) | ((uint64_t)Rd);
+ Rd = (uint32_t)(resTemp & 0xffffffff);
+ Rn = (uint32_t)(resTemp >> 32);
+ }}, llbit);
0x6: smull({{
resTemp = ((int64_t)(int32_t)Rm)*
((int64_t)(int32_t)Rs);
Rd = (int32_t)(resTemp & 0xffffffff);
Rn = (int32_t)(resTemp >> 32);
- }});
+ }}, llbit);
0x7: umlal({{
resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
resTemp += ((uint64_t)Rn << 32)+((uint64_t)Rd);
Rd = (uint32_t)(resTemp & 0xffffffff);
Rn = (uint32_t)(resTemp >> 32);
- }});
+ }}, llbit);
}
1: decode PUBWL {
0x10: WarnUnimpl::swp();
@@ -91,9 +96,9 @@ format DataOp {
0x2: sub({{ Rd = resTemp = Rn - op2; }}, sub);
0x3: rsb({{ Rd = resTemp = op2 - Rn; }}, rsb);
0x4: add({{ Rd = resTemp = Rn + op2; }}, add);
- 0x5: adc({{ Rd = resTemp = Rn + op2 + Cpsr<29:>; }}, add);
- 0x6: sbc({{ Rd = resTemp = Rn - op2 - !Cpsr<29:>; }}, sub);
- 0x7: rsc({{ Rd = resTemp = op2 - Rn - !Cpsr<29:>; }}, rsb);
+ 0x5: adc({{ Rd = resTemp = Rn + op2 + CondCodes<29:>; }}, add);
+ 0x6: sbc({{ Rd = resTemp = Rn - op2 - !CondCodes<29:>; }}, sub);
+ 0x7: rsc({{ Rd = resTemp = op2 - Rn - !CondCodes<29:>; }}, rsb);
0x8: tst({{ resTemp = Rn & op2; }});
0x9: teq({{ resTemp = Rn ^ op2; }});
0xa: cmp({{ resTemp = Rn - op2; }}, sub);
@@ -105,10 +110,37 @@ format DataOp {
}
1: decode MISC_OPCODE {
0x0: decode OPCODE {
- 0x8: WarnUnimpl::mrs_cpsr();
- 0x9: WarnUnimpl::msr_cpsr();
- 0xa: WarnUnimpl::mrs_spsr();
- 0xb: WarnUnimpl::msr_spsr();
+ 0x8: PredOp::mrs_cpsr({{
+ Rd = (Cpsr | CondCodes) & 0xF8FF03DF;
+ }});
+ 0x9: decode USEIMM {
+ // The mask field is the same as the RN index.
+ 0: PredOp::msr_cpsr_reg({{
+ uint32_t newCpsr =
+ cpsrWriteByInstr(Cpsr | CondCodes,
+ Rm, RN, false);
+ Cpsr = ~CondCodesMask & newCpsr;
+ CondCodes = CondCodesMask & newCpsr;
+ }});
+ 1: PredImmOp::msr_cpsr_imm({{
+ uint32_t newCpsr =
+ cpsrWriteByInstr(Cpsr | CondCodes,
+ rotated_imm, RN, false);
+ Cpsr = ~CondCodesMask & newCpsr;
+ CondCodes = CondCodesMask & newCpsr;
+ }});
+ }
+ 0xa: PredOp::mrs_spsr({{ Rd = Spsr; }});
+ 0xb: decode USEIMM {
+ // The mask field is the same as the RN index.
+ 0: PredOp::msr_spsr_reg({{
+ Spsr = spsrWriteByInstr(Spsr, Rm, RN, false);
+ }});
+ 1: PredImmOp::msr_spsr_imm({{
+ Spsr = spsrWriteByInstr(Spsr, rotated_imm,
+ RN, false);
+ }});
+ }
}
0x1: decode OPCODE {
0x9: BranchExchange::bx({{ }});
@@ -129,28 +161,32 @@ format DataOp {
0xb: WarnUnimpl::qdsub();
}
0x8: decode OPCODE {
- 0x8: WarnUnimpl::smlabb();
+ 0x8: smlabb({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<15:0>) + Rd; }}, overflow);
0x9: WarnUnimpl::smlalbb();
0xa: WarnUnimpl::smlawb();
- 0xb: WarnUnimpl::smulbb();
+ 0xb: smulbb({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<15:0>); }}, none);
}
0xa: decode OPCODE {
- 0x8: WarnUnimpl::smlatb();
- 0x9: WarnUnimpl::smulwb();
+ 0x8: smlatb({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<15:0>) + Rd; }}, overflow);
+ 0x9: smulwb({{
+ Rn = resTemp = bits(sext<32>(Rm) * sext<16>(Rs<15:0>), 47, 16);
+ }}, none);
0xa: WarnUnimpl::smlaltb();
- 0xb: WarnUnimpl::smultb();
+ 0xb: smultb({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<15:0>); }}, none);
}
0xc: decode OPCODE {
- 0x8: WarnUnimpl::smlabt();
+ 0x8: smlabt({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<31:16>) + Rd; }}, overflow);
0x9: WarnUnimpl::smlawt();
0xa: WarnUnimpl::smlalbt();
- 0xb: WarnUnimpl::smulbt();
+ 0xb: smulbt({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<31:16>); }}, none);
}
0xe: decode OPCODE {
- 0x8: WarnUnimpl::smlatt();
- 0x9: WarnUnimpl::smulwt();
+ 0x8: smlatt({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<31:16>) + Rd; }}, overflow);
+ 0x9: smulwt({{
+ Rn = resTemp = bits(sext<32>(Rm) * sext<16>(Rs<31:16>), 47, 16);
+ }}, none);
0xa: WarnUnimpl::smlaltt();
- 0xb: WarnUnimpl::smultt();
+ 0xb: smultt({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<31:16>); }}, none);
}
}
}
@@ -163,9 +199,15 @@ format DataOp {
0x2: subi({{ Rd = resTemp = Rn - rotated_imm; }}, sub);
0x3: rsbi({{ Rd = resTemp = rotated_imm - Rn; }}, rsb);
0x4: addi({{ Rd = resTemp = Rn + rotated_imm; }}, add);
- 0x5: adci({{ Rd = resTemp = Rn + rotated_imm + Cpsr<29:>; }}, add);
- 0x6: sbci({{ Rd = resTemp = Rn -rotated_imm - !Cpsr<29:>; }}, sub);
- 0x7: rsci({{ Rd = resTemp = rotated_imm - Rn - !Cpsr<29:>;}}, rsb);
+ 0x5: adci({{
+ Rd = resTemp = Rn + rotated_imm + CondCodes<29:>;
+ }}, add);
+ 0x6: sbci({{
+ Rd = resTemp = Rn -rotated_imm - !CondCodes<29:>;
+ }}, sub);
+ 0x7: rsci({{
+ Rd = resTemp = rotated_imm - Rn - !CondCodes<29:>;
+ }}, rsb);
0x8: tsti({{ resTemp = Rn & rotated_imm; }});
0x9: teqi({{ resTemp = Rn ^ rotated_imm; }});
0xa: cmpi({{ resTemp = Rn - rotated_imm; }}, sub);
@@ -178,11 +220,27 @@ format DataOp {
}
1: decode OPCODE {
// The following two instructions aren't supposed to be defined
- 0x8: WarnUnimpl::undefined_instruction();
- 0x9: WarnUnimpl::undefined_instruction();
-
- 0xa: WarnUnimpl::mrs_i_cpsr();
- 0xb: WarnUnimpl::mrs_i_spsr();
+ 0x8: DataOp::movw({{ Rd = IMMED_11_0 | (RN << 12) ; }});
+ 0x9: decode RN {
+ 0: decode IMM {
+ 0: PredImmOp::nop({{ ; }});
+ 1: WarnUnimpl::yield();
+ 2: WarnUnimpl::wfe();
+ 3: WarnUnimpl::wfi();
+ 4: WarnUnimpl::sev();
+ }
+ default: PredImmOp::msr_i_cpsr({{
+ uint32_t newCpsr =
+ cpsrWriteByInstr(Cpsr | CondCodes,
+ rotated_imm, RN, false);
+ Cpsr = ~CondCodesMask & newCpsr;
+ CondCodes = CondCodesMask & newCpsr;
+ }});
+ }
+ 0xa: PredOp::movt({{ Rd = IMMED_11_0 << 16 | RN << 28 | Rd<15:0>; }});
+ 0xb: PredImmOp::msr_i_spsr({{
+ Spsr = spsrWriteByInstr(Spsr, rotated_imm, RN, false);
+ }});
}
}
0x2: AddrMode2::addrMode2(Disp, disp);
@@ -324,77 +382,79 @@ format DataOp {
}
}
0x7: decode OPCODE_24 {
- 0: decode CPNUM {
- // Coprocessor Instructions
- 0x1: decode OPCODE_4 {
+ 0: decode OPCODE_4 {
+ 0: decode CPNUM {
format FloatOp {
- // Basic FPA Instructions
- 0: decode OPCODE_23_20 {
- 0x0: decode OPCODE_15 {
- 0: adf({{ Fd.sf = Fn.sf + Fm.sf; }});
- 1: mvf({{ Fd.sf = Fm.sf; }});
- }
- 0x1: decode OPCODE_15 {
- 0: muf({{ Fd.sf = Fn.sf * Fm.sf; }});
- 1: mnf({{ Fd.sf = -Fm.sf; }});
- }
- 0x2: decode OPCODE_15 {
- 0: suf({{ Fd.sf = Fn.sf - Fm.sf; }});
- 1: abs({{ Fd.sf = fabs(Fm.sf); }});
- }
- 0x3: decode OPCODE_15 {
- 0: rsf({{ Fd.sf = Fm.sf - Fn.sf; }});
- 1: rnd({{ Fd.sf = rint(Fm.sf); }});
- }
- 0x4: decode OPCODE_15 {
- 0: dvf({{ Fd.sf = Fn.sf / Fm.sf; }});
- 1: sqt({{ Fd.sf = sqrt(Fm.sf); }});
- }
- 0x5: decode OPCODE_15 {
- 0: rdf({{ Fd.sf = Fm.sf / Fn.sf; }});
- 1: log({{ Fd.sf = log10(Fm.sf); }});
- }
- 0x6: decode OPCODE_15 {
- 0: pow({{ Fd.sf = pow(Fm.sf, Fn.sf); }});
- 1: lgn({{ Fd.sf = log(Fm.sf); }});
- }
- 0x7: decode OPCODE_15 {
- 0: rpw({{ Fd.sf = pow(Fn.sf, Fm.sf); }});
- 1: exp({{ Fd.sf = exp(Fm.sf); }});
- }
- 0x8: decode OPCODE_15 {
- 0: rmf({{ Fd.sf = drem(Fn.sf, Fm.sf); }});
- 1: sin({{ Fd.sf = sin(Fm.sf); }});
- }
- 0x9: decode OPCODE_15 {
- 0: fml({{ Fd.sf = Fn.sf * Fm.sf; }});
- 1: cos({{ Fd.sf = cos(Fm.sf); }});
- }
- 0xa: decode OPCODE_15 {
- 0: fdv({{ Fd.sf = Fn.sf / Fm.sf; }});
- 1: tan({{ Fd.sf = tan(Fm.sf); }});
- }
- 0xb: decode OPCODE_15 {
- 0: frd({{ Fd.sf = Fm.sf / Fn.sf; }});
- 1: asn({{ Fd.sf = asin(Fm.sf); }});
- }
- 0xc: decode OPCODE_15 {
- 0: pol({{ Fd.sf = atan2(Fn.sf, Fm.sf); }});
- 1: acs({{ Fd.sf = acos(Fm.sf); }});
- }
- 0xd: decode OPCODE_15 {
- 1: atn({{ Fd.sf = atan(Fm.sf); }});
- }
- 0xe: decode OPCODE_15 {
- // Unnormalised Round
- 1: FailUnimpl::urd();
- }
- 0xf: decode OPCODE_15 {
- // Normalise
- 1: FailUnimpl::nrm();
- }
- }
- 1: decode OPCODE_15_12 {
+ 0x1: decode OPCODE_23_20 {
+ 0x0: decode OPCODE_15 {
+ 0: adf({{ Fd.sf = Fn.sf + Fm.sf; }});
+ 1: mvf({{ Fd.sf = Fm.sf; }});
+ }
+ 0x1: decode OPCODE_15 {
+ 0: muf({{ Fd.sf = Fn.sf * Fm.sf; }});
+ 1: mnf({{ Fd.sf = -Fm.sf; }});
+ }
+ 0x2: decode OPCODE_15 {
+ 0: suf({{ Fd.sf = Fn.sf - Fm.sf; }});
+ 1: abs({{ Fd.sf = fabs(Fm.sf); }});
+ }
+ 0x3: decode OPCODE_15 {
+ 0: rsf({{ Fd.sf = Fm.sf - Fn.sf; }});
+ 1: rnd({{ Fd.sf = rint(Fm.sf); }});
+ }
+ 0x4: decode OPCODE_15 {
+ 0: dvf({{ Fd.sf = Fn.sf / Fm.sf; }});
+ 1: sqt({{ Fd.sf = sqrt(Fm.sf); }});
+ }
+ 0x5: decode OPCODE_15 {
+ 0: rdf({{ Fd.sf = Fm.sf / Fn.sf; }});
+ 1: log({{ Fd.sf = log10(Fm.sf); }});
+ }
+ 0x6: decode OPCODE_15 {
+ 0: pow({{ Fd.sf = pow(Fm.sf, Fn.sf); }});
+ 1: lgn({{ Fd.sf = log(Fm.sf); }});
+ }
+ 0x7: decode OPCODE_15 {
+ 0: rpw({{ Fd.sf = pow(Fn.sf, Fm.sf); }});
+ 1: exp({{ Fd.sf = exp(Fm.sf); }});
+ }
+ 0x8: decode OPCODE_15 {
+ 0: rmf({{ Fd.sf = drem(Fn.sf, Fm.sf); }});
+ 1: sin({{ Fd.sf = sin(Fm.sf); }});
+ }
+ 0x9: decode OPCODE_15 {
+ 0: fml({{ Fd.sf = Fn.sf * Fm.sf; }});
+ 1: cos({{ Fd.sf = cos(Fm.sf); }});
+ }
+ 0xa: decode OPCODE_15 {
+ 0: fdv({{ Fd.sf = Fn.sf / Fm.sf; }});
+ 1: tan({{ Fd.sf = tan(Fm.sf); }});
+ }
+ 0xb: decode OPCODE_15 {
+ 0: frd({{ Fd.sf = Fm.sf / Fn.sf; }});
+ 1: asn({{ Fd.sf = asin(Fm.sf); }});
+ }
+ 0xc: decode OPCODE_15 {
+ 0: pol({{ Fd.sf = atan2(Fn.sf, Fm.sf); }});
+ 1: acs({{ Fd.sf = acos(Fm.sf); }});
+ }
+ 0xd: decode OPCODE_15 {
+ 1: atn({{ Fd.sf = atan(Fm.sf); }});
+ }
+ 0xe: decode OPCODE_15 {
+ // Unnormalised Round
+ 1: FailUnimpl::urd();
+ }
+ 0xf: decode OPCODE_15 {
+ // Normalise
+ 1: FailUnimpl::nrm();
+ }
+ } // OPCODE_23_20
+ } // format FloatOp
+ } // CPNUM
+ 1: decode CPNUM { // 27-24=1110,4 ==1
+ 1: decode OPCODE_15_12 {
+ format FloatOp {
0xf: decode OPCODE_23_21 {
format FloatCmp {
0x4: cmf({{ Fn.df }}, {{ Fm.df }});
@@ -417,36 +477,86 @@ format DataOp {
0x4: FailUnimpl::wfc();
0x5: FailUnimpl::rfc();
}
- }
+ } // format FloatOp
}
- }
- 0xa: decode MISC_OPCODE {
- 0x1: decode MEDIA_OPCODE {
- 0xf: decode RN {
- 0x0: FloatOp::fmrx_fpsid({{ Rd = Fpsid; }});
- 0x1: FloatOp::fmrx_fpscr({{ Rd = Fpscr; }});
- 0x8: FloatOp::fmrx_fpexc({{ Rd = Fpexc; }});
- }
- 0xe: decode RN {
- 0x0: FloatOp::fmxr_fpsid({{ Fpsid = Rd; }});
- 0x1: FloatOp::fmxr_fpscr({{ Fpscr = Rd; }});
- 0x8: FloatOp::fmxr_fpexc({{ Fpexc = Rd; }});
+ 0xa: decode MISC_OPCODE {
+ 0x1: decode MEDIA_OPCODE {
+ 0xf: decode RN {
+ 0x0: FloatOp::fmrx_fpsid({{ Rd = Fpsid; }});
+ 0x1: FloatOp::fmrx_fpscr({{ Rd = Fpscr; }});
+ 0x8: FloatOp::fmrx_fpexc({{ Rd = Fpexc; }});
+ }
+ 0xe: decode RN {
+ 0x0: FloatOp::fmxr_fpsid({{ Fpsid = Rd; }});
+ 0x1: FloatOp::fmxr_fpscr({{ Fpscr = Rd; }});
+ 0x8: FloatOp::fmxr_fpexc({{ Fpexc = Rd; }});
+ }
+ } // MEDIA_OPCODE (MISC_OPCODE 0x1)
+ } // MISC_OPCODE (CPNUM 0xA)
+ 0xf: decode RN {
+ // Barrriers, Cache Maintence, NOPS
+ 7: decode OPCODE_23_21 {
+ 0: decode RM {
+ 0: decode OPC2 {
+ 4: decode OPCODE_20 {
+ 0: PredOp::mcr_cp15_nop1({{ }}); // was wfi
+ }
+ }
+ 1: WarnUnimpl::cp15_cache_maint();
+ 4: WarnUnimpl::cp15_par();
+ 5: decode OPC2 {
+ 0,1: WarnUnimpl::cp15_cache_maint2();
+ 4: PredOp::cp15_isb({{ ; }}, IsMemBarrier, IsSerializeBefore);
+ 6,7: WarnUnimpl::cp15_bp_maint();
+ }
+ 6: WarnUnimpl::cp15_cache_maint3();
+ 8: WarnUnimpl::cp15_va_to_pa();
+ 10: decode OPC2 {
+ 1,2: WarnUnimpl::cp15_cache_maint3();
+ 4: PredOp::cp15_dsb({{ ; }}, IsMemBarrier, IsSerializeBefore);
+ 5: PredOp::cp15_dmb({{ ; }}, IsMemBarrier, IsSerializeBefore);
+ }
+ 11: WarnUnimpl::cp15_cache_maint4();
+ 13: decode OPC2 {
+ 1: decode OPCODE_20 {
+ 0: PredOp::mcr_cp15_nop2({{ }}); // was prefetch
+ }
+ }
+ 14: WarnUnimpl::cp15_cache_maint5();
+ } // RM
+ } // OPCODE_23_21 CR
+
+ // Thread ID and context ID registers
+ // Thread ID register needs cheaper access than miscreg
+ 13: WarnUnimpl::mcr_mrc_cp15_c7();
+
+ // All the rest
+ default: decode OPCODE_20 {
+ 0: PredOp::mcr_cp15({{
+ fault = setCp15Register(Rd, RN, OPCODE_23_21, RM, OPC2);
+ }});
+ 1: PredOp::mrc_cp15({{
+ fault = readCp15Register(Rd, RN, OPCODE_23_21, RM, OPC2);
+ }});
}
- }
+ } // RN
+ } // CPNUM (OP4 == 1)
+ } //OPCODE_4
+
+#if FULL_SYSTEM
+ 1: PredOp::swi({{ fault = new SupervisorCall; }}, IsSerializeAfter, IsNonSpeculative, IsSyscall);
+#else
+ 1: PredOp::swi({{ if (testPredicate(CondCodes, condCode))
+ {
+ if (IMMED_23_0)
+ xc->syscall(IMMED_23_0);
+ else
+ xc->syscall(R7);
}
- }
- format PredOp {
- // ARM System Call (SoftWare Interrupt)
- 1: swi({{ if (testPredicate(Cpsr, condCode))
- {
- if (IMMED_23_0)
- xc->syscall(IMMED_23_0);
- else
- xc->syscall(R7);
- }
- }});
- }
- }
+ }});
+#endif // FULL_SYSTEM
+ } // OPCODE_24
+
}
}
diff --git a/src/arch/arm/isa/formats/branch.isa b/src/arch/arm/isa/formats/branch.isa
index 95f4f14e1..5f1b541ff 100644
--- a/src/arch/arm/isa/formats/branch.isa
+++ b/src/arch/arm/isa/formats/branch.isa
@@ -52,7 +52,7 @@ def format Branch(code,*opt_flags) {{
else:
inst_flags += ('IsCondControl', )
- icode = 'if (testPredicate(Cpsr, condCode)) {\n'
+ icode = 'if (testPredicate(CondCodes, condCode)) {\n'
icode += code
icode += ' NPC = NPC + 4 + disp;\n'
icode += '} else {\n'
@@ -90,7 +90,7 @@ def format BranchExchange(code,*opt_flags) {{
#Condition code
- icode = 'if (testPredicate(Cpsr, condCode)) {\n'
+ icode = 'if (testPredicate(CondCodes, condCode)) {\n'
icode += code
icode += ' NPC = Rm & 0xfffffffe; // Masks off bottom bit\n'
icode += '} else {\n'
diff --git a/src/arch/arm/isa/formats/fp.isa b/src/arch/arm/isa/formats/fp.isa
index e88531580..e79529615 100644
--- a/src/arch/arm/isa/formats/fp.isa
+++ b/src/arch/arm/isa/formats/fp.isa
@@ -119,8 +119,8 @@ let {{
_ic = %(fReg1)s >= %(fReg2)s;
_iv = (isnan(%(fReg1)s) || isnan(%(fReg2)s)) & 1;
- Cpsr = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
- (Cpsr & 0x0FFFFFFF);
+ CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
+ (CondCodes & 0x0FFFFFFF);
'''
}};
diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa
index 355a67ea9..c834c22cb 100644
--- a/src/arch/arm/isa/formats/macromem.isa
+++ b/src/arch/arm/isa/formats/macromem.isa
@@ -72,6 +72,18 @@ let {{
'predicate_test': predicateTest},
['IsMicroop'])
+ microLdrRetUopCode = '''
+ Ra = Mem;
+ Cpsr = cpsrWriteByInstr(Cpsr, Spsr, 0xF, true);
+ '''
+ microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop',
+ 'MicroMemOp',
+ {'memacc_code': microLdrRetUopCode,
+ 'ea_code':
+ 'EA = Rb + (UP ? imm : -imm);',
+ 'predicate_test': predicateTest},
+ ['IsMicroop'])
+
microStrUopIop = InstObjParams('str_uop', 'MicroStrUop',
'MicroMemOp',
{'memacc_code': 'Mem = Ra;',
@@ -80,14 +92,19 @@ let {{
['IsMicroop'])
header_output = MicroMemDeclare.subst(microLdrUopIop) + \
+ MicroMemDeclare.subst(microLdrRetUopIop) + \
MicroMemDeclare.subst(microStrUopIop)
decoder_output = MicroConstructor.subst(microLdrUopIop) + \
+ MicroConstructor.subst(microLdrRetUopIop) + \
MicroConstructor.subst(microStrUopIop)
exec_output = LoadExecute.subst(microLdrUopIop) + \
+ LoadExecute.subst(microLdrRetUopIop) + \
StoreExecute.subst(microStrUopIop) + \
LoadInitiateAcc.subst(microLdrUopIop) + \
+ LoadInitiateAcc.subst(microLdrRetUopIop) + \
StoreInitiateAcc.subst(microStrUopIop) + \
LoadCompleteAcc.subst(microLdrUopIop) + \
+ LoadCompleteAcc.subst(microLdrRetUopIop) + \
StoreCompleteAcc.subst(microStrUopIop)
}};
@@ -178,73 +195,64 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
{
%(constructor)s;
- uint32_t regs_to_handle = reglist;
- uint32_t start_addr = 0;
+ uint32_t regs = reglist;
+ uint32_t addr = 0;
+ bool up = machInst.puswl.up;
- switch (puswl)
- {
- case 0x00: // stmda
- case 0x01: // L ldmda_l
- case 0x02: // W stmda_w
- case 0x03: // WL ldmda_wl
- start_addr = (ones << 2) - 4;
- break;
- case 0x08: // U stmia_u
- case 0x09: // U L ldmia_ul
- case 0x0a: // U W stmia
- case 0x0b: // U WL ldmia
- start_addr = 0;
- break;
- case 0x10: // P stmdb
- case 0x11: // P L ldmdb
- case 0x12: // P W stmdb
- case 0x13: // P WL ldmdb
- start_addr = (ones << 2); // U-bit is already 0 for subtract
- break;
- case 0x18: // PU stmib
- case 0x19: // PU L ldmib
- case 0x1a: // PU W stmib
- case 0x1b: // PU WL ldmib
- start_addr = 4;
- break;
- default:
- panic("Unhandled Load/Store Multiple Instruction, "
- "puswl = 0x%x", (unsigned) puswl);
- break;
- }
+ if (!up)
+ addr = (ones << 2) - 4;
+
+ if (machInst.puswl.prepost)
+ addr += 4;
- // Add 0 to Rn and stick it in Raddr (register 17).
+ // Add 0 to Rn and stick it in ureg0.
// This is equivalent to a move.
- microOps[0] = new MicroAddiUop(machInst, 17, RN, 0);
+ microOps[0] = new MicroAddiUop(machInst, INTREG_UREG0, RN, 0);
- unsigned j = 0;
- for (int i = 1; i < ones+1; i++) {
- // Get next available bit for transfer
- while (! ( regs_to_handle & (1<<j)))
- j++;
- regs_to_handle &= ~(1<<j);
+ unsigned reg = 0;
+ bool force_user = machInst.puswl.psruser & !OPCODE_15;
+ bool exception_ret = machInst.puswl.psruser & OPCODE_15;
- if (loadop)
- microOps[i] = new MicroLdrUop(machInst, j, 17, start_addr);
- else
- microOps[i] = new MicroStrUop(machInst, j, 17, start_addr);
+ for (int i = 1; i < ones + 1; i++) {
+ // Find the next register.
+ while (!bits(regs, reg))
+ reg++;
+ replaceBits(regs, reg, 0);
+
+ unsigned regIdx = reg;
+ if (force_user) {
+ regIdx = intRegForceUser(regIdx);
+ }
+
+ if (machInst.puswl.loadOp) {
+ if (reg == INTREG_PC && exception_ret) {
+ // This must be the exception return form of ldm.
+ microOps[i] =
+ new MicroLdrRetUop(machInst, regIdx, INTREG_UREG0, addr);
+ } else {
+ microOps[i] =
+ new MicroLdrUop(machInst, regIdx, INTREG_UREG0, addr);
+ }
+ } else {
+ microOps[i] =
+ new MicroStrUop(machInst, regIdx, INTREG_UREG0, addr);
+ }
if (up)
- start_addr += 4;
+ addr += 4;
else
- start_addr -= 4;
+ addr -= 4;
}
- if (writeback) {
+ StaticInstPtr &lastUop = microOps[numMicroops - 1];
+ if (machInst.puswl.writeback) {
if (up) {
- microOps[numMicroops-1] =
- new MicroAddiUop(machInst, RN, RN, ones * 4);
+ lastUop = new MicroAddiUop(machInst, RN, RN, ones * 4);
} else {
- microOps[numMicroops-1] =
- new MicroSubiUop(machInst, RN, RN, ones * 4);
+ lastUop = new MicroSubiUop(machInst, RN, RN, ones * 4);
}
}
- microOps[numMicroops-1]->setLastMicroop();
+ lastUop->setLastMicroop();
}
}};
@@ -285,14 +293,14 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
if (writeback)
{
if (up) {
- microOps[numMicroops-1] =
+ microOps[numMicroops - 1] =
new MicroAddiUop(machInst, RN, RN, disp8);
} else {
- microOps[numMicroops-1] =
+ microOps[numMicroops - 1] =
new MicroSubiUop(machInst, RN, RN, disp8);
}
}
- microOps[numMicroops-1]->setLastMicroop();
+ microOps[numMicroops - 1]->setLastMicroop();
}
}};
@@ -316,14 +324,14 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
if (writeback) {
if (up) {
- microOps[numMicroops-1] =
+ microOps[numMicroops - 1] =
new MicroAddiUop(machInst, RN, RN, disp8);
} else {
- microOps[numMicroops-1] =
+ microOps[numMicroops - 1] =
new MicroSubiUop(machInst, RN, RN, disp8);
}
}
- microOps[numMicroops-1]->setLastMicroop();
+ microOps[numMicroops - 1]->setLastMicroop();
}
}};
diff --git a/src/arch/arm/isa/formats/pred.isa b/src/arch/arm/isa/formats/pred.isa
index e90788c91..0d6ee32f7 100644
--- a/src/arch/arm/isa/formats/pred.isa
+++ b/src/arch/arm/isa/formats/pred.isa
@@ -34,7 +34,7 @@
//
let {{
- predicateTest = 'testPredicate(Cpsr, condCode)'
+ predicateTest = 'testPredicate(CondCodes, condCode)'
}};
def template PredOpExecute {{
@@ -81,32 +81,45 @@ def template DataImmDecode {{
}};
let {{
+
+ calcCcCode = '''
+ if (%(canOverflow)s){
+ cprintf("canOverflow: %%d\\n", Rd < resTemp);
+ replaceBits(CondCodes, 27, Rd < resTemp);
+ } else {
+ uint16_t _ic, _iv, _iz, _in;
+ _in = (resTemp >> %(negBit)d) & 1;
+ _iz = (resTemp == 0);
+ _iv = %(ivValue)s & 1;
+ _ic = %(icValue)s & 1;
+
+ CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
+ (CondCodes & 0x0FFFFFFF);
- calcCcCode = '''
- uint16_t _ic, _iv, _iz, _in;
-
- _in = (resTemp >> 31) & 1;
- _iz = (resTemp == 0);
- _iv = %(ivValue)s & 1;
- _ic = %(icValue)s & 1;
-
- Cpsr = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
- (Cpsr & 0x0FFFFFFF);
-
- DPRINTF(Arm, "in = %%d\\n", _in);
- DPRINTF(Arm, "iz = %%d\\n", _iz);
- DPRINTF(Arm, "ic = %%d\\n", _ic);
- DPRINTF(Arm, "iv = %%d\\n", _iv);
+ DPRINTF(Arm, "in = %%d\\n", _in);
+ DPRINTF(Arm, "iz = %%d\\n", _iz);
+ DPRINTF(Arm, "ic = %%d\\n", _ic);
+ DPRINTF(Arm, "iv = %%d\\n", _iv);
+ }
'''
-
}};
let {{
def getCcCode(flagtype):
icReg = icImm = iv = ''
+ negBit = 31
+ canOverflow = 'false'
+
if flagtype == "none":
- icReg = icImm = 'Cpsr<29:>'
- iv = 'Cpsr<28:>'
+ icReg = icImm = 'CondCodes<29:>'
+ iv = 'CondCodes<28:>'
+ elif flagtype == "llbit":
+ icReg = icImm = 'CondCodes<29:>'
+ iv = 'CondCodes<28:>'
+ negBit = 63
+ elif flagtype == "overflow":
+ canOverflow = "true"
+ icReg = icImm = iv = '0'
elif flagtype == "add":
icReg = icImm = 'findCarry(32, resTemp, Rn, op2)'
iv = 'findOverflow(32, resTemp, Rn, op2)'
@@ -117,17 +130,32 @@ let {{
icReg = icImm = 'findCarry(32, resTemp, op2, ~Rn)'
iv = 'findOverflow(32, resTemp, op2, ~Rn)'
else:
- icReg = 'shift_carry_rs(Rm, Rs, shift, Cpsr<29:>)'
- icImm = 'shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>)'
- iv = 'Cpsr<28:>'
- return (calcCcCode % {"icValue" : icReg, "ivValue" : iv},
- calcCcCode % {"icValue" : icImm, "ivValue" : iv})
+ icReg = 'shift_carry_rs(Rm, Rs<7:0>, shift, CondCodes<29:>)'
+ icImm = 'shift_carry_imm(Rm, shift_size, shift, CondCodes<29:>)'
+ iv = 'CondCodes<28:>'
+ return (calcCcCode % {"icValue" : icReg,
+ "ivValue" : iv,
+ "negBit" : negBit,
+ "canOverflow" : canOverflow },
+ calcCcCode % {"icValue" : icImm,
+ "ivValue" : iv,
+ "negBit" : negBit,
+ "canOverflow" : canOverflow })
def getImmCcCode(flagtype):
ivValue = icValue = ''
+ negBit = 31
+ canOverflow = 'false'
if flagtype == "none":
- icValue = 'Cpsr<29:>'
- ivValue = 'Cpsr<28:>'
+ icValue = 'CondCodes<29:>'
+ ivValue = 'CondCodes<28:>'
+ elif flagtype == "llbit":
+ icValue = 'CondCodes<29:>'
+ ivValue = 'CondCodes<28:>'
+ negBit = 63
+ elif flagtype == "overflow":
+ icVaule = ivValue = '0'
+ canOverflow = "true"
elif flagtype == "add":
icValue = 'findCarry(32, resTemp, Rn, rotated_imm)'
ivValue = 'findOverflow(32, resTemp, Rn, rotated_imm)'
@@ -138,18 +166,18 @@ let {{
icValue = 'findCarry(32, resTemp, rotated_imm, ~Rn)'
ivValue = 'findOverflow(32, resTemp, rotated_imm, ~Rn)'
else:
- icValue = '(rotate ? rotated_carry:Cpsr<29:>)'
- ivValue = 'Cpsr<28:>'
+ icValue = '(rotate ? rotated_carry:CondCodes<29:>)'
+ ivValue = 'CondCodes<28:>'
return calcCcCode % vars()
}};
def format DataOp(code, flagtype = logic) {{
(regCcCode, immCcCode) = getCcCode(flagtype)
- regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs,
- shift, Cpsr<29:0>);
+ regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs<7:0>,
+ shift, CondCodes<29:>);
op2 = op2;''' + code
immCode = '''uint32_t op2 = shift_rm_imm(Rm, shift_size,
- shift, Cpsr<29:0>);
+ shift, CondCodes<29:>);
op2 = op2;''' + code
regIop = InstObjParams(name, Name, 'PredIntOp',
{"code": regCode,
diff --git a/src/arch/arm/isa/formats/unimp.isa b/src/arch/arm/isa/formats/unimp.isa
index c82bb41c6..6909c3f85 100644
--- a/src/arch/arm/isa/formats/unimp.isa
+++ b/src/arch/arm/isa/formats/unimp.isa
@@ -115,7 +115,7 @@ output exec {{
panic("attempt to execute unimplemented instruction '%s' "
"(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
inst2string(machInst));
- return new UnimplementedOpcodeFault;
+ return new UnimpFault("Unimplemented Instruction");
}
Fault
diff --git a/src/arch/arm/isa/formats/unknown.isa b/src/arch/arm/isa/formats/unknown.isa
index 2ad7a2506..97a0caa6b 100644
--- a/src/arch/arm/isa/formats/unknown.isa
+++ b/src/arch/arm/isa/formats/unknown.isa
@@ -74,7 +74,7 @@ output exec {{
{
panic("attempt to execute unknown instruction "
"(inst 0x%08x, opcode 0x%x, binary: %s)", machInst, OPCODE, inst2string(machInst));
- return new UnimplementedOpcodeFault;
+ return new UnimpFault("Unimplemented Instruction");
}
}};
diff --git a/src/arch/arm/isa/formats/util.isa b/src/arch/arm/isa/formats/util.isa
index b5efec568..d42ffb147 100644
--- a/src/arch/arm/isa/formats/util.isa
+++ b/src/arch/arm/isa/formats/util.isa
@@ -33,8 +33,10 @@ let {{
# Generic substitutions for Arm instructions
def ArmGenericCodeSubs(code):
# Substitute in the shifted portion of operations
- new_code = re.sub(r'Rm_Imm', 'shift_rm_imm(Rm, shift_size, shift, Cpsr<29:>)', code)
- new_code = re.sub(r'Rm_Rs', 'shift_rm_rs(Rm, Rs, shift, Cpsr<29:>)', new_code)
+ new_code = re.sub(r'Rm_Imm',
+ 'shift_rm_imm(Rm, shift_size, shift, CondCodes<29:>)', code)
+ new_code = re.sub(r'Rm_Rs',
+ 'shift_rm_rs(Rm, Rs, shift, CondCodes<29:>)', new_code)
return new_code
def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa
index ac7427dad..aadefc79c 100644
--- a/src/arch/arm/isa/operands.isa
+++ b/src/arch/arm/isa/operands.isa
@@ -58,15 +58,16 @@ def operands {{
'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 3, maybePCRead, maybePCWrite),
'Rn': ('IntReg', 'uw', 'RN', 'IsInteger', 4, maybePCRead, maybePCWrite),
'R7': ('IntReg', 'uw', '7', 'IsInteger', 5),
+ 'R0': ('IntReg', 'uw', '0', 'IsInteger', 0),
#Destination register for load/store double instructions
'Rdo': ('IntReg', 'uw', '(RD & ~1)', 'IsInteger', 4, maybePCRead, maybePCWrite),
'Rde': ('IntReg', 'uw', '(RD | 1)', 'IsInteger', 5, maybePCRead, maybePCWrite),
- 'Raddr': ('IntReg', 'uw', '17', 'IsInteger', 6),
- 'Rhi': ('IntReg', 'uw', '18', 'IsInteger', 7),
- 'Rlo': ('IntReg', 'uw', '19', 'IsInteger', 8),
- 'LR': ('IntReg', 'uw', '14', 'IsInteger', 9),
+ 'Rhi': ('IntReg', 'uw', 'INTREG_RHI', 'IsInteger', 7),
+ 'Rlo': ('IntReg', 'uw', 'INTREG_RLO', 'IsInteger', 8),
+ 'LR': ('IntReg', 'uw', 'INTREG_LR', 'IsInteger', 9),
+ 'CondCodes': ('IntReg', 'uw', 'INTREG_CONDCODES', 'IsInteger', 10),
#Register fields for microops
'Ra' : ('IntReg', 'uw', 'ura', 'IsInteger', 11, maybePCRead, maybePCWrite),
@@ -80,12 +81,13 @@ def operands {{
#Memory Operand
'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 30),
- 'Cpsr': ('ControlReg', 'uw', 'MISCREG_CPSR', 'IsInteger', 40),
- 'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', 'IsInteger', 41),
- 'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', 'IsInteger', 42),
- 'Fpscr': ('ControlReg', 'uw', 'MISCREG_FPSCR', 'IsInteger', 43),
- 'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', 'IsInteger', 44),
- 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 45),
- 'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 46)
+ 'Cpsr': ('ControlReg', 'uw', 'MISCREG_CPSR', (None, None, 'IsControl'), 40),
+ 'Spsr': ('ControlReg', 'uw', 'MISCREG_SPSR', (None, None, 'IsControl'), 41),
+ 'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', (None, None, 'IsControl'), 42),
+ 'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', (None, None, 'IsControl'), 43),
+ 'Fpscr': ('ControlReg', 'uw', 'MISCREG_FPSCR', (None, None, 'IsControl'), 44),
+ 'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', (None, None, 'IsControl'), 45),
+ 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 50),
+ 'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 51)
}};
diff --git a/src/arch/arm/isa_traits.hh b/src/arch/arm/isa_traits.hh
index 542174b6b..91c51c46b 100644
--- a/src/arch/arm/isa_traits.hh
+++ b/src/arch/arm/isa_traits.hh
@@ -104,6 +104,8 @@ namespace ArmISA
const int WordBytes = 4;
const int HalfwordBytes = 2;
const int ByteBytes = 1;
+
+ const uint32_t HighVecs = 0xFFFF0000;
};
using namespace ArmISA;
diff --git a/src/mem/slicc/ast/TypeAST.cc b/src/arch/arm/kernel_stats.hh
index 7590b4e7c..18bdc500d 100644
--- a/src/mem/slicc/ast/TypeAST.cc
+++ b/src/arch/arm/kernel_stats.hh
@@ -1,6 +1,5 @@
-
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2004-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,43 +24,34 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * TypeAST.C
- *
- * Description: See TypeAST.hh
- *
- * $Id: TypeAST.C,v 3.1 2003/03/22 15:15:16 xu Exp $
*
+ * Authors: Gabe Black
*/
-#include "mem/slicc/ast/TypeAST.hh"
+#ifndef __ARCH_ARM_KERNEL_STATS_HH__
+#define __ARCH_ARM_KERNEL_STATS_HH__
-TypeAST::TypeAST(string* ident_ptr)
- : AST()
-{
- m_ident_ptr = ident_ptr;
-}
+#include <map>
+#include <stack>
+#include <string>
+#include <vector>
-TypeAST::~TypeAST()
-{
- delete m_ident_ptr;
+#include "kern/kernel_stats.hh"
-}
+namespace ArmISA {
+namespace Kernel {
-string TypeAST::toString() const
-{
- return *m_ident_ptr;
-}
+enum cpu_mode { hypervisor, kernel, user, idle, cpu_mode_num };
+extern const char *modestr[];
-Type* TypeAST::lookupType() const
+class Statistics : public ::Kernel::Statistics
{
- Type* type_ptr = g_sym_table.getType(*m_ident_ptr);
- if (type_ptr != NULL) {
- return type_ptr;
- } else {
- error("Type '" + *m_ident_ptr + "' not declared.");
- }
- return NULL; // Not reached
-}
+ public:
+ Statistics(System *system) : ::Kernel::Statistics(system)
+ {}
+};
+
+} /* end namespace ArmISA::Kernel */
+} /* end namespace ArmISA */
+
+#endif // __ARCH_ARM_KERNEL_STATS_HH__
diff --git a/src/arch/arm/linux/linux.hh b/src/arch/arm/linux/linux.hh
index d99fa8e49..f829dd7c6 100644
--- a/src/arch/arm/linux/linux.hh
+++ b/src/arch/arm/linux/linux.hh
@@ -86,6 +86,7 @@ class ArmLinux : public Linux
static const unsigned TIOCISATTY_ = 0x2000745e;
static const unsigned TIOCGETS_ = 0x402c7413;
static const unsigned TIOCGETA_ = 0x40127417;
+ static const unsigned TCSETAW_ = 0x5407; // 2.6.15 kernel
//@}
/// For table().
@@ -147,6 +148,21 @@ class ArmLinux : public Linux
uint64_t st_ino;
} tgt_stat64;
+ typedef struct {
+ int32_t uptime; /* Seconds since boot */
+ uint32_t loads[3]; /* 1, 5, and 15 minute load averages */
+ uint32_t totalram; /* Total usable main memory size */
+ uint32_t freeram; /* Available memory size */
+ uint32_t sharedram; /* Amount of shared memory */
+ uint32_t bufferram; /* Memory used by buffers */
+ uint32_t totalswap; /* Total swap space size */
+ uint32_t freeswap; /* swap space still available */
+ uint16_t procs; /* Number of current processes */
+ uint32_t totalhigh; /* Total high memory size */
+ uint32_t freehigh; /* Available high memory size */
+ uint32_t mem_unit; /* Memory unit size in bytes */
+ } tgt_sysinfo;
+
};
diff --git a/src/arch/arm/linux/process.cc b/src/arch/arm/linux/process.cc
index 56e3588a7..f909d871a 100644
--- a/src/arch/arm/linux/process.cc
+++ b/src/arch/arm/linux/process.cc
@@ -50,7 +50,8 @@ static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
+ int index = 0;
+ TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, index));
strcpy(name->sysname, "Linux");
strcpy(name->nodename, "m5.eecs.umich.edu");
@@ -179,7 +180,7 @@ SyscallDesc ArmLinuxProcess::syscallDescs[] = {
/* 113 */ SyscallDesc("vm86", unimplementedFunc),
/* 114 */ SyscallDesc("wait4", unimplementedFunc),
/* 115 */ SyscallDesc("swapoff", unimplementedFunc),
- /* 116 */ SyscallDesc("sysinfo", unimplementedFunc),
+ /* 116 */ SyscallDesc("sysinfo", sysinfoFunc<ArmLinux>),
/* 117 */ SyscallDesc("ipc", unimplementedFunc),
/* 118 */ SyscallDesc("fsync", unimplementedFunc),
/* 119 */ SyscallDesc("sigreturn", unimplementedFunc),
@@ -417,7 +418,8 @@ static SyscallReturn
setTLSFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- uint32_t tlsPtr = process->getSyscallArg(tc, 0);
+ int index = 0;
+ uint32_t tlsPtr = process->getSyscallArg(tc, index);
tc->getMemPort()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0,
(uint8_t *)&tlsPtr, sizeof(tlsPtr));
@@ -511,12 +513,12 @@ ArmLinuxProcess::startup()
}
ArmISA::IntReg
-ArmLinuxProcess::getSyscallArg(ThreadContext *tc, int i)
+ArmLinuxProcess::getSyscallArg(ThreadContext *tc, int &i)
{
// Linux apparently allows more parameter than the ABI says it should.
// This limit may need to be increased even further.
assert(i < 6);
- return tc->readIntReg(ArgumentReg0 + i);
+ return tc->readIntReg(ArgumentReg0 + i++);
}
void
diff --git a/src/arch/arm/linux/process.hh b/src/arch/arm/linux/process.hh
index 53b3781d2..ab836fab2 100644
--- a/src/arch/arm/linux/process.hh
+++ b/src/arch/arm/linux/process.hh
@@ -44,7 +44,7 @@ class ArmLinuxProcess : public ArmLiveProcess
void startup();
- ArmISA::IntReg getSyscallArg(ThreadContext *tc, int i);
+ ArmISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
void setSyscallArg(ThreadContext *tc, int i, ArmISA::IntReg val);
/// The target system's hostname.
diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh
index 3180669de..d100efb8e 100644
--- a/src/arch/arm/miscregs.hh
+++ b/src/arch/arm/miscregs.hh
@@ -55,23 +55,24 @@ namespace ArmISA
enum MiscRegIndex {
MISCREG_CPSR = 0,
- MISCREG_SPSR,
+ MISCREG_SPSR,
MISCREG_SPSR_FIQ,
MISCREG_SPSR_IRQ,
MISCREG_SPSR_SVC,
+ MISCREG_SPSR_MON,
MISCREG_SPSR_UND,
MISCREG_SPSR_ABT,
MISCREG_FPSR,
MISCREG_FPSID,
MISCREG_FPSCR,
MISCREG_FPEXC,
- NUM_MISCREGS
+ MISCREG_SCTLR,
+ NUM_MISCREGS
};
const char * const miscRegName[NUM_MISCREGS] = {
- "cpsr",
- "spsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_und", "spsr_abt",
- "fpsr"
+ "cpsr", "spsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_und",
+ "spsr_abt", "fpsr", "fpsid", "fpscr", "fpexc", "sctlr"
};
BitUnion32(CPSR)
@@ -80,8 +81,10 @@ namespace ArmISA
Bitfield<29> c;
Bitfield<28> v;
Bitfield<27> q;
+ Bitfield<26,25> it1;
Bitfield<24> j;
Bitfield<19, 16> ge;
+ Bitfield<15,10> it2;
Bitfield<9> e;
Bitfield<8> a;
Bitfield<7> i;
@@ -89,6 +92,35 @@ namespace ArmISA
Bitfield<5> t;
Bitfield<4, 0> mode;
EndBitUnion(CPSR)
+
+ // This mask selects bits of the CPSR that actually go in the CondCodes
+ // integer register to allow renaming.
+ static const uint32_t CondCodesMask = 0xF80F0000;
+
+ BitUnion32(SCTLR)
+ Bitfield<30> te; // Thumb Exception Enable
+ Bitfield<29> afe; // Access flag enable
+ Bitfield<28> tre; // TEX Remap bit
+ Bitfield<27> nmfi;// Non-maskable fast interrupts enable
+ Bitfield<25> ee; // Exception Endianness bit
+ Bitfield<24> ve; // Interrupt vectors enable
+ Bitfield<23> rao1;// Read as one
+ Bitfield<22> u; // Alignment (now unused)
+ Bitfield<21> fi; // Fast interrupts configuration enable
+ Bitfield<18> rao2;// Read as one
+ Bitfield<17> ha; // Hardware access flag enable
+ Bitfield<16> rao3;// Read as one
+ Bitfield<14> rr; // Round robin cache replacement
+ Bitfield<13> v; // Base address for exception vectors
+ Bitfield<12> i; // instruction cache enable
+ Bitfield<11> z; // branch prediction enable bit
+ Bitfield<10> sw; // Enable swp/swpb
+ Bitfield<6,3> rao4;// Read as one
+ Bitfield<7> b; // Endianness support (unused)
+ Bitfield<2> c; // Cache enable bit
+ Bitfield<1> a; // Alignment fault checking
+ Bitfield<0> m; // MMU enable bit
+ EndBitUnion(SCTLR)
};
#endif // __ARCH_ARM_MISCREGS_HH__
diff --git a/src/arch/arm/nativetrace.cc b/src/arch/arm/nativetrace.cc
index 1ad9e1a19..01f3205eb 100644
--- a/src/arch/arm/nativetrace.cc
+++ b/src/arch/arm/nativetrace.cc
@@ -97,7 +97,8 @@ Trace::ArmNativeTrace::ThreadState::update(ThreadContext *tc)
changed[STATE_PC] = (newState[STATE_PC] != oldState[STATE_PC]);
//CPSR
- newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR);
+ newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR) |
+ tc->readIntReg(INTREG_CONDCODES);
changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]);
}
diff --git a/src/arch/arm/process.cc b/src/arch/arm/process.cc
index cd7cc9736..702922a43 100644
--- a/src/arch/arm/process.cc
+++ b/src/arch/arm/process.cc
@@ -324,10 +324,10 @@ ArmLiveProcess::argsInit(int intSize, int pageSize)
}
ArmISA::IntReg
-ArmLiveProcess::getSyscallArg(ThreadContext *tc, int i)
+ArmLiveProcess::getSyscallArg(ThreadContext *tc, int &i)
{
assert(i < 4);
- return tc->readIntReg(ArgumentReg0 + i);
+ return tc->readIntReg(ArgumentReg0 + i++);
}
void
diff --git a/src/arch/arm/process.hh b/src/arch/arm/process.hh
index 8954d3719..f793892d0 100644
--- a/src/arch/arm/process.hh
+++ b/src/arch/arm/process.hh
@@ -53,7 +53,7 @@ class ArmLiveProcess : public LiveProcess
public:
void argsInit(int intSize, int pageSize);
- ArmISA::IntReg getSyscallArg(ThreadContext *tc, int i);
+ ArmISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
void setSyscallArg(ThreadContext *tc, int i, ArmISA::IntReg val);
void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
};
diff --git a/src/arch/arm/registers.hh b/src/arch/arm/registers.hh
index 7f9b6b828..41bbf4e7f 100644
--- a/src/arch/arm/registers.hh
+++ b/src/arch/arm/registers.hh
@@ -32,6 +32,7 @@
#define __ARCH_ARM_REGISTERS_HH__
#include "arch/arm/max_inst_regs.hh"
+#include "arch/arm/intregs.hh"
#include "arch/arm/miscregs.hh"
namespace ArmISA {
@@ -51,13 +52,11 @@ typedef float FloatReg;
typedef uint64_t MiscReg;
// Constants Related to the number of registers
-const int NumIntArchRegs = 16;
-const int NumIntSpecialRegs = 19;
+const int NumIntArchRegs = NUM_ARCH_INTREGS;
const int NumFloatArchRegs = 16;
const int NumFloatSpecialRegs = 5;
-const int NumInternalProcRegs = 0;
-const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs;
+const int NumIntRegs = NUM_INTREGS;
const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;
const int NumMiscRegs = NUM_MISCREGS;
@@ -72,12 +71,11 @@ const int ArgumentReg1 = 1;
const int ArgumentReg2 = 2;
const int ArgumentReg3 = 3;
const int FramePointerReg = 11;
-const int StackPointerReg = 13;
-const int ReturnAddressReg = 14;
-const int PCReg = 15;
+const int StackPointerReg = INTREG_SP;
+const int ReturnAddressReg = INTREG_LR;
+const int PCReg = INTREG_PC;
-const int ZeroReg = NumIntArchRegs;
-const int AddrReg = ZeroReg + 1; // Used to generate address for uops
+const int ZeroReg = INTREG_ZERO;
const int SyscallNumReg = ReturnValueReg;
const int SyscallPseudoReturnReg = ReturnValueReg;
@@ -116,35 +114,6 @@ enum FCSRFields {
Cause_Field = 11
};
-enum MiscIntRegNums {
- zero_reg = NumIntArchRegs,
- addr_reg,
-
- rhi,
- rlo,
-
- r8_fiq, /* FIQ mode register bank */
- r9_fiq,
- r10_fiq,
- r11_fiq,
- r12_fiq,
-
- r13_fiq, /* FIQ mode SP and LR */
- r14_fiq,
-
- r13_irq, /* IRQ mode SP and LR */
- r14_irq,
-
- r13_svc, /* SVC mode SP and LR */
- r14_svc,
-
- r13_undef, /* UNDEF mode SP and LR */
- r14_undef,
-
- r13_abt, /* ABT mode SP and LR */
- r14_abt
-};
-
} // namespace ArmISA
#endif
diff --git a/src/arch/arm/stacktrace.cc b/src/arch/arm/stacktrace.cc
new file mode 100644
index 000000000..6b346b0ab
--- /dev/null
+++ b/src/arch/arm/stacktrace.cc
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
+ */
+
+#include <string>
+
+#include "arch/arm/isa_traits.hh"
+#include "arch/arm/stacktrace.hh"
+#include "arch/arm/vtophys.hh"
+#include "base/bitfield.hh"
+#include "base/trace.hh"
+#include "cpu/base.hh"
+#include "cpu/thread_context.hh"
+#include "sim/system.hh"
+
+using namespace std;
+namespace ArmISA
+{
+ ProcessInfo::ProcessInfo(ThreadContext *_tc)
+ : tc(_tc)
+ {
+ Addr addr = 0;
+
+ VirtualPort *vp;
+
+ vp = tc->getVirtPort();
+
+ if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
+ panic("thread info not compiled into kernel\n");
+ thread_info_size = vp->readGtoH<int32_t>(addr);
+
+ if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr))
+ panic("thread info not compiled into kernel\n");
+ task_struct_size = vp->readGtoH<int32_t>(addr);
+
+ if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr))
+ panic("thread info not compiled into kernel\n");
+ task_off = vp->readGtoH<int32_t>(addr);
+
+ if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr))
+ panic("thread info not compiled into kernel\n");
+ pid_off = vp->readGtoH<int32_t>(addr);
+
+ if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr))
+ panic("thread info not compiled into kernel\n");
+ name_off = vp->readGtoH<int32_t>(addr);
+ }
+
+ Addr
+ ProcessInfo::task(Addr ksp) const
+ {
+ return 0;
+ }
+
+ int
+ ProcessInfo::pid(Addr ksp) const
+ {
+ return -1;
+ }
+
+ string
+ ProcessInfo::name(Addr ksp) const
+ {
+ return "Implement me";
+ }
+
+ StackTrace::StackTrace()
+ : tc(0), stack(64)
+ {
+ }
+
+ StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst)
+ : tc(0), stack(64)
+ {
+ trace(_tc, inst);
+ }
+
+ StackTrace::~StackTrace()
+ {
+ }
+
+ void
+ StackTrace::trace(ThreadContext *_tc, bool is_call)
+ {
+ }
+
+ bool
+ StackTrace::isEntry(Addr addr)
+ {
+ return false;
+ }
+
+ bool
+ StackTrace::decodeStack(MachInst inst, int &disp)
+ {
+ return false;
+ }
+
+ bool
+ StackTrace::decodeSave(MachInst inst, int &reg, int &disp)
+ {
+ return false;
+ }
+
+ /*
+ * Decode the function prologue for the function we're in, and note
+ * which registers are stored where, and how large the stack frame is.
+ */
+ bool
+ StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func,
+ int &size, Addr &ra)
+ {
+ return false;
+ }
+
+#if TRACING_ON
+ void
+ StackTrace::dump()
+ {
+ DPRINTFN("------ Stack ------\n");
+
+ DPRINTFN(" Not implemented\n");
+ }
+#endif
+}
diff --git a/src/arch/arm/stacktrace.hh b/src/arch/arm/stacktrace.hh
index 3f9c91096..05fdb9e78 100644
--- a/src/arch/arm/stacktrace.hh
+++ b/src/arch/arm/stacktrace.hh
@@ -1,6 +1,5 @@
/*
* Copyright (c) 2005 The Regents of The University of Michigan
- * Copyright (c) 2007-2008 The Florida State University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,8 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * Authors: Ali Saidi
- * Stephen Hines
+ * Authors: Nathan Binkert
*/
#ifndef __ARCH_ARM_STACKTRACE_HH__
@@ -37,11 +35,11 @@
#include "cpu/static_inst.hh"
class ThreadContext;
-class StackTrace;
-
namespace ArmISA
{
+class StackTrace;
+
class ProcessInfo
{
private:
@@ -64,7 +62,7 @@ class ProcessInfo
class StackTrace
{
protected:
- typedef TheISA::MachInst MachInst;
+ typedef ArmISA::MachInst MachInst;
private:
ThreadContext *tc;
std::vector<Addr> stack;
@@ -94,10 +92,6 @@ class StackTrace
public:
const std::vector<Addr> &getstack() const { return stack; }
- static const int user = 1;
- static const int console = 2;
- static const int unknown = 3;
-
#if TRACING_ON
private:
void dump();
@@ -123,6 +117,6 @@ StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
return true;
}
-}
+} // Namespace ArmISA
#endif // __ARCH_ARM_STACKTRACE_HH__
diff --git a/src/mem/slicc/ast/TypeFieldAST.cc b/src/arch/arm/system.cc
index 5657d023c..e7470f89a 100644
--- a/src/mem/slicc/ast/TypeFieldAST.cc
+++ b/src/arch/arm/system.cc
@@ -1,6 +1,5 @@
-
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2002-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,20 +24,28 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * TypeFieldAST.C
- *
- * Description: See TypeFieldAST.hh
- *
- * $Id$
*
+ * Authors: Ali Saidi
*/
-#include "mem/slicc/ast/TypeFieldAST.hh"
+#include "arch/arm/system.hh"
+
-TypeFieldAST::TypeFieldAST(PairListAST* pairs_ptr)
- : AST(pairs_ptr->getPairs()) {
+using namespace LittleEndianGuest;
+
+ArmSystem::ArmSystem(Params *p)
+ : System(p)
+{
+
+}
+
+ArmSystem::~ArmSystem()
+{
}
+
+ArmSystem *
+ArmSystemParams::create()
+{
+ return new ArmSystem(this);
+}
diff --git a/src/mem/slicc/ast/StatementAST.cc b/src/arch/arm/system.hh
index 35627722a..9dfb66fb7 100644
--- a/src/mem/slicc/ast/StatementAST.cc
+++ b/src/arch/arm/system.hh
@@ -1,6 +1,5 @@
-
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2002-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,36 +24,33 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * StatementAST.C
- *
- * Description: See StatementAST.hh
- *
- * $Id$
*
+ * Authors: Ali Saidi
*/
-#include "mem/slicc/ast/StatementAST.hh"
+#ifndef __ARCH_ARM_SYSTEM_HH__
+#define __ARCH_ARM_SYSTEM_HH__
-static int indentation_depth = 1;
+#include <string>
+#include <vector>
-void inc_indent()
-{
- indentation_depth++;
-}
+#include "params/ArmSystem.hh"
+#include "sim/sim_object.hh"
+#include "sim/system.hh"
-void dec_indent()
+class ArmSystem : public System
{
- indentation_depth--;
-}
+ public:
+ typedef ArmSystemParams Params;
+ ArmSystem(Params *p);
+ ~ArmSystem();
+
+ virtual Addr fixFuncEventAddr(Addr addr)
+ {
+ //XXX This may eventually have to do something useful.
+ return addr;
+ }
+};
+
+#endif
-string indent_str()
-{
- string temp;
- for(int i=0; i<indentation_depth; i++) {
- temp += " ";
- }
- return temp;
-}
diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc
index febc6d081..864c061a2 100644
--- a/src/arch/arm/tlb.cc
+++ b/src/arch/arm/tlb.cc
@@ -287,7 +287,15 @@ TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
return NoFault;
#else
- fatal("translate atomic not yet implemented\n");
+ SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
+ if (!sctlr.m) {
+ req->setPaddr(req->getVaddr());
+ return NoFault;
+ }
+ panic("MMU translation not implemented\n");
+ return NoFault;
+
+
#endif
}
diff --git a/src/arch/arm/types.hh b/src/arch/arm/types.hh
index 2c4e1291c..e0b3951b9 100644
--- a/src/arch/arm/types.hh
+++ b/src/arch/arm/types.hh
@@ -45,16 +45,20 @@ namespace ArmISA
// All the different types of opcode fields.
Bitfield<27, 25> encoding;
+ Bitfield<25> useImm;
Bitfield<24, 21> opcode;
Bitfield<24, 20> mediaOpcode;
Bitfield<24> opcode24;
Bitfield<23, 20> opcode23_20;
Bitfield<23, 21> opcode23_21;
+ Bitfield<20> opcode20;
Bitfield<22> opcode22;
Bitfield<19> opcode19;
+ Bitfield<18> opcode18;
Bitfield<15, 12> opcode15_12;
Bitfield<15> opcode15;
Bitfield<7, 4> miscOpcode;
+ Bitfield<7,5> opc2;
Bitfield<7> opcode7;
Bitfield<4> opcode4;
@@ -156,6 +160,7 @@ namespace ArmISA
MODE_FIQ = 17,
MODE_IRQ = 18,
MODE_SVC = 19,
+ MODE_MON = 22,
MODE_ABORT = 23,
MODE_UNDEFINED = 27,
MODE_SYSTEM = 31
diff --git a/src/mem/slicc/ast/ExprStatementAST.cc b/src/arch/arm/utility.cc
index f4bffaab3..5ce32542b 100644
--- a/src/mem/slicc/ast/ExprStatementAST.cc
+++ b/src/arch/arm/utility.cc
@@ -1,6 +1,5 @@
-
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009 ARM Limited
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,49 +24,53 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * ExprStatementAST.C
- *
- * Description: See ExprStatementAST.hh
- *
- * $Id$
*
+ * Authors: Ali Saidi
*/
-#include "mem/slicc/ast/ExprStatementAST.hh"
-ExprStatementAST::ExprStatementAST(ExprAST* expr_ptr)
- : StatementAST()
+#include "arch/arm/faults.hh"
+#include "arch/arm/utility.hh"
+#include "cpu/thread_context.hh"
+
+
+namespace ArmISA {
+
+void
+initCPU(ThreadContext *tc, int cpuId)
{
- m_expr_ptr = expr_ptr;
+ // Reset CP15?? What does that mean -- ali
+
+ // FPEXC.EN = 0
+
+ static Fault reset = new Reset;
+ if (cpuId == 0)
+ reset->invoke(tc);
}
-ExprStatementAST::~ExprStatementAST()
-{
- delete m_expr_ptr;
+uint64_t getArgument(ThreadContext *tc, int number, bool fp) {
+#if FULL_SYSTEM
+ panic("getArgument() not implemented for ARM!\n");
+#else
+ panic("getArgument() only implemented for FULL_SYSTEM\n");
+ M5_DUMMY_RETURN
+#endif
}
-void ExprStatementAST::generate(string& code, Type* return_type_ptr) const
+Fault
+setCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2)
{
- code += indent_str();
- Type* actual_type_ptr = m_expr_ptr->generate(code);
- code += ";\n";
-
- // The return type must be void
- Type* expected_type_ptr = g_sym_table.getType("void");
- if (expected_type_ptr != actual_type_ptr) {
- m_expr_ptr->error("Non-void return must not be ignored, return type is '" + actual_type_ptr->toString() + "'");
- }
+ return new UnimpFault(csprintf("MCR CP15: CRn: %d opc1: %d CRm: %d opc1: %d\n",
+ CRn, opc1, CRm, opc2));
}
-void ExprStatementAST::findResources(Map<Var*, string>& resource_list) const
+Fault
+readCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2)
{
- m_expr_ptr->findResources(resource_list);
+ return new UnimpFault(csprintf("MRC CP15: CRn: %d opc1: %d CRm: %d opc1: %d\n",
+ CRn, opc1, CRm, opc2));
+
}
-void ExprStatementAST::print(ostream& out) const
-{
- out << "[ExprStatementAST: " << *m_expr_ptr << "]";
+
}
diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh
index a2f0ef170..3ddfd12dd 100644
--- a/src/arch/arm/utility.hh
+++ b/src/arch/arm/utility.hh
@@ -125,6 +125,20 @@ namespace ArmISA {
{
panic("Copy Misc. Regs Not Implemented Yet\n");
}
+
+ void initCPU(ThreadContext *tc, int cpuId);
+
+ static inline bool
+ inUserMode(ThreadContext *tc)
+ {
+ return (tc->readMiscRegNoEffect(MISCREG_CPSR) & 0x1f) == MODE_USER;
+ }
+
+uint64_t getArgument(ThreadContext *tc, int number, bool fp);
+
+Fault setCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2);
+Fault readCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2);
+
};
diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py
index d5b5bbe4f..2db7c6aa6 100755
--- a/src/arch/isa_parser.py
+++ b/src/arch/isa_parser.py
@@ -34,702 +34,704 @@ import traceback
# get type names
from types import *
-# Prepend the directory where the PLY lex & yacc modules are found
-# to the search path. Assumes we're compiling in a subdirectory
-# of 'build' in the current tree.
-sys.path[0:0] = [os.environ['M5_PLY']]
-
-from ply import lex
-from ply import yacc
-
-#####################################################################
-#
-# Lexer
-#
-# The PLY lexer module takes two things as input:
-# - A list of token names (the string list 'tokens')
-# - A regular expression describing a match for each token. The
-# regexp for token FOO can be provided in two ways:
-# - as a string variable named t_FOO
-# - as the doc string for a function named t_FOO. In this case,
-# the function is also executed, allowing an action to be
-# associated with each token match.
-#
-#####################################################################
-
-# Reserved words. These are listed separately as they are matched
-# using the same regexp as generic IDs, but distinguished in the
-# t_ID() function. The PLY documentation suggests this approach.
-reserved = (
- 'BITFIELD', 'DECODE', 'DECODER', 'DEFAULT', 'DEF', 'EXEC', 'FORMAT',
- 'HEADER', 'LET', 'NAMESPACE', 'OPERAND_TYPES', 'OPERANDS',
- 'OUTPUT', 'SIGNED', 'TEMPLATE'
+from m5.util.grammar import Grammar
+
+class ISAParser(Grammar):
+ def __init__(self, *args, **kwargs):
+ super(ISAParser, self).__init__(*args, **kwargs)
+ self.templateMap = {}
+
+ #####################################################################
+ #
+ # Lexer
+ #
+ # The PLY lexer module takes two things as input:
+ # - A list of token names (the string list 'tokens')
+ # - A regular expression describing a match for each token. The
+ # regexp for token FOO can be provided in two ways:
+ # - as a string variable named t_FOO
+ # - as the doc string for a function named t_FOO. In this case,
+ # the function is also executed, allowing an action to be
+ # associated with each token match.
+ #
+ #####################################################################
+
+ # Reserved words. These are listed separately as they are matched
+ # using the same regexp as generic IDs, but distinguished in the
+ # t_ID() function. The PLY documentation suggests this approach.
+ reserved = (
+ 'BITFIELD', 'DECODE', 'DECODER', 'DEFAULT', 'DEF', 'EXEC', 'FORMAT',
+ 'HEADER', 'LET', 'NAMESPACE', 'OPERAND_TYPES', 'OPERANDS',
+ 'OUTPUT', 'SIGNED', 'TEMPLATE'
+ )
+
+ # List of tokens. The lex module requires this.
+ tokens = reserved + (
+ # identifier
+ 'ID',
+
+ # integer literal
+ 'INTLIT',
+
+ # string literal
+ 'STRLIT',
+
+ # code literal
+ 'CODELIT',
+
+ # ( ) [ ] { } < > , ; . : :: *
+ 'LPAREN', 'RPAREN',
+ 'LBRACKET', 'RBRACKET',
+ 'LBRACE', 'RBRACE',
+ 'LESS', 'GREATER', 'EQUALS',
+ 'COMMA', 'SEMI', 'DOT', 'COLON', 'DBLCOLON',
+ 'ASTERISK',
+
+ # C preprocessor directives
+ 'CPPDIRECTIVE'
+
+ # The following are matched but never returned. commented out to
+ # suppress PLY warning
+ # newfile directive
+ # 'NEWFILE',
+
+ # endfile directive
+ # 'ENDFILE'
)
-# List of tokens. The lex module requires this.
-tokens = reserved + (
- # identifier
- 'ID',
-
- # integer literal
- 'INTLIT',
-
- # string literal
- 'STRLIT',
-
- # code literal
- 'CODELIT',
-
- # ( ) [ ] { } < > , ; . : :: *
- 'LPAREN', 'RPAREN',
- 'LBRACKET', 'RBRACKET',
- 'LBRACE', 'RBRACE',
- 'LESS', 'GREATER', 'EQUALS',
- 'COMMA', 'SEMI', 'DOT', 'COLON', 'DBLCOLON',
- 'ASTERISK',
-
- # C preprocessor directives
- 'CPPDIRECTIVE'
-
-# The following are matched but never returned. commented out to
-# suppress PLY warning
- # newfile directive
-# 'NEWFILE',
-
- # endfile directive
-# 'ENDFILE'
-)
-
-# Regular expressions for token matching
-t_LPAREN = r'\('
-t_RPAREN = r'\)'
-t_LBRACKET = r'\['
-t_RBRACKET = r'\]'
-t_LBRACE = r'\{'
-t_RBRACE = r'\}'
-t_LESS = r'\<'
-t_GREATER = r'\>'
-t_EQUALS = r'='
-t_COMMA = r','
-t_SEMI = r';'
-t_DOT = r'\.'
-t_COLON = r':'
-t_DBLCOLON = r'::'
-t_ASTERISK = r'\*'
-
-# Identifiers and reserved words
-reserved_map = { }
-for r in reserved:
- reserved_map[r.lower()] = r
-
-def t_ID(t):
- r'[A-Za-z_]\w*'
- t.type = reserved_map.get(t.value,'ID')
- return t
-
-# Integer literal
-def t_INTLIT(t):
- r'(0x[\da-fA-F]+)|\d+'
- try:
- t.value = int(t.value,0)
- except ValueError:
- error(t.lexer.lineno, 'Integer value "%s" too large' % t.value)
- t.value = 0
- return t
-
-# String literal. Note that these use only single quotes, and
-# can span multiple lines.
-def t_STRLIT(t):
- r"(?m)'([^'])+'"
- # strip off quotes
- t.value = t.value[1:-1]
- t.lexer.lineno += t.value.count('\n')
- return t
-
-
-# "Code literal"... like a string literal, but delimiters are
-# '{{' and '}}' so they get formatted nicely under emacs c-mode
-def t_CODELIT(t):
- r"(?m)\{\{([^\}]|}(?!\}))+\}\}"
- # strip off {{ & }}
- t.value = t.value[2:-2]
- t.lexer.lineno += t.value.count('\n')
- return t
-
-def t_CPPDIRECTIVE(t):
- r'^\#[^\#].*\n'
- t.lexer.lineno += t.value.count('\n')
- return t
-
-def t_NEWFILE(t):
- r'^\#\#newfile\s+"[\w/.-]*"'
- fileNameStack.push((t.value[11:-1], t.lexer.lineno))
- t.lexer.lineno = 0
-
-def t_ENDFILE(t):
- r'^\#\#endfile'
- (old_filename, t.lexer.lineno) = fileNameStack.pop()
-
-#
-# The functions t_NEWLINE, t_ignore, and t_error are
-# special for the lex module.
-#
-
-# Newlines
-def t_NEWLINE(t):
- r'\n+'
- t.lexer.lineno += t.value.count('\n')
-
-# Comments
-def t_comment(t):
- r'//.*'
-
-# Completely ignored characters
-t_ignore = ' \t\x0c'
-
-# Error handler
-def t_error(t):
- error(t.lexer.lineno, "illegal character '%s'" % t.value[0])
- t.skip(1)
-
-# Build the lexer
-lexer = lex.lex()
-
-#####################################################################
-#
-# Parser
-#
-# Every function whose name starts with 'p_' defines a grammar rule.
-# The rule is encoded in the function's doc string, while the
-# function body provides the action taken when the rule is matched.
-# The argument to each function is a list of the values of the
-# rule's symbols: t[0] for the LHS, and t[1..n] for the symbols
-# on the RHS. For tokens, the value is copied from the t.value
-# attribute provided by the lexer. For non-terminals, the value
-# is assigned by the producing rule; i.e., the job of the grammar
-# rule function is to set the value for the non-terminal on the LHS
-# (by assigning to t[0]).
-#####################################################################
-
-# The LHS of the first grammar rule is used as the start symbol
-# (in this case, 'specification'). Note that this rule enforces
-# that there will be exactly one namespace declaration, with 0 or more
-# global defs/decls before and after it. The defs & decls before
-# the namespace decl will be outside the namespace; those after
-# will be inside. The decoder function is always inside the namespace.
-def p_specification(t):
- 'specification : opt_defs_and_outputs name_decl opt_defs_and_outputs decode_block'
- global_code = t[1]
- isa_name = t[2]
- namespace = isa_name + "Inst"
- # wrap the decode block as a function definition
- t[4].wrap_decode_block('''
+ # Regular expressions for token matching
+ t_LPAREN = r'\('
+ t_RPAREN = r'\)'
+ t_LBRACKET = r'\['
+ t_RBRACKET = r'\]'
+ t_LBRACE = r'\{'
+ t_RBRACE = r'\}'
+ t_LESS = r'\<'
+ t_GREATER = r'\>'
+ t_EQUALS = r'='
+ t_COMMA = r','
+ t_SEMI = r';'
+ t_DOT = r'\.'
+ t_COLON = r':'
+ t_DBLCOLON = r'::'
+ t_ASTERISK = r'\*'
+
+ # Identifiers and reserved words
+ reserved_map = { }
+ for r in reserved:
+ reserved_map[r.lower()] = r
+
+ def t_ID(self, t):
+ r'[A-Za-z_]\w*'
+ t.type = self.reserved_map.get(t.value, 'ID')
+ return t
+
+ # Integer literal
+ def t_INTLIT(self, t):
+ r'(0x[\da-fA-F]+)|\d+'
+ try:
+ t.value = int(t.value,0)
+ except ValueError:
+ error(t.lexer.lineno, 'Integer value "%s" too large' % t.value)
+ t.value = 0
+ return t
+
+ # String literal. Note that these use only single quotes, and
+ # can span multiple lines.
+ def t_STRLIT(self, t):
+ r"(?m)'([^'])+'"
+ # strip off quotes
+ t.value = t.value[1:-1]
+ t.lexer.lineno += t.value.count('\n')
+ return t
+
+
+ # "Code literal"... like a string literal, but delimiters are
+ # '{{' and '}}' so they get formatted nicely under emacs c-mode
+ def t_CODELIT(self, t):
+ r"(?m)\{\{([^\}]|}(?!\}))+\}\}"
+ # strip off {{ & }}
+ t.value = t.value[2:-2]
+ t.lexer.lineno += t.value.count('\n')
+ return t
+
+ def t_CPPDIRECTIVE(self, t):
+ r'^\#[^\#].*\n'
+ t.lexer.lineno += t.value.count('\n')
+ return t
+
+ def t_NEWFILE(self, t):
+ r'^\#\#newfile\s+"[\w/.-]*"'
+ fileNameStack.push((t.value[11:-1], t.lexer.lineno))
+ t.lexer.lineno = 0
+
+ def t_ENDFILE(self, t):
+ r'^\#\#endfile'
+ (old_filename, t.lexer.lineno) = fileNameStack.pop()
+
+ #
+ # The functions t_NEWLINE, t_ignore, and t_error are
+ # special for the lex module.
+ #
+
+ # Newlines
+ def t_NEWLINE(self, t):
+ r'\n+'
+ t.lexer.lineno += t.value.count('\n')
+
+ # Comments
+ def t_comment(self, t):
+ r'//.*'
+
+ # Completely ignored characters
+ t_ignore = ' \t\x0c'
+
+ # Error handler
+ def t_error(self, t):
+ error(t.lexer.lineno, "illegal character '%s'" % t.value[0])
+ t.skip(1)
+
+ #####################################################################
+ #
+ # Parser
+ #
+ # Every function whose name starts with 'p_' defines a grammar
+ # rule. The rule is encoded in the function's doc string, while
+ # the function body provides the action taken when the rule is
+ # matched. The argument to each function is a list of the values
+ # of the rule's symbols: t[0] for the LHS, and t[1..n] for the
+ # symbols on the RHS. For tokens, the value is copied from the
+ # t.value attribute provided by the lexer. For non-terminals, the
+ # value is assigned by the producing rule; i.e., the job of the
+ # grammar rule function is to set the value for the non-terminal
+ # on the LHS (by assigning to t[0]).
+ #####################################################################
+
+ # The LHS of the first grammar rule is used as the start symbol
+ # (in this case, 'specification'). Note that this rule enforces
+ # that there will be exactly one namespace declaration, with 0 or
+ # more global defs/decls before and after it. The defs & decls
+ # before the namespace decl will be outside the namespace; those
+ # after will be inside. The decoder function is always inside the
+ # namespace.
+ def p_specification(self, t):
+ 'specification : opt_defs_and_outputs name_decl opt_defs_and_outputs decode_block'
+ global_code = t[1]
+ isa_name = t[2]
+ namespace = isa_name + "Inst"
+ # wrap the decode block as a function definition
+ t[4].wrap_decode_block('''
StaticInstPtr
%(isa_name)s::decodeInst(%(isa_name)s::ExtMachInst machInst)
{
using namespace %(namespace)s;
''' % vars(), '}')
- # both the latter output blocks and the decode block are in the namespace
- namespace_code = t[3] + t[4]
- # pass it all back to the caller of yacc.parse()
- t[0] = (isa_name, namespace, global_code, namespace_code)
-
-# ISA name declaration looks like "namespace <foo>;"
-def p_name_decl(t):
- 'name_decl : NAMESPACE ID SEMI'
- t[0] = t[2]
-
-# 'opt_defs_and_outputs' is a possibly empty sequence of
-# def and/or output statements.
-def p_opt_defs_and_outputs_0(t):
- 'opt_defs_and_outputs : empty'
- t[0] = GenCode()
-
-def p_opt_defs_and_outputs_1(t):
- 'opt_defs_and_outputs : defs_and_outputs'
- t[0] = t[1]
-
-def p_defs_and_outputs_0(t):
- 'defs_and_outputs : def_or_output'
- t[0] = t[1]
-
-def p_defs_and_outputs_1(t):
- 'defs_and_outputs : defs_and_outputs def_or_output'
- t[0] = t[1] + t[2]
-
-# The list of possible definition/output statements.
-def p_def_or_output(t):
- '''def_or_output : def_format
- | def_bitfield
- | def_bitfield_struct
- | def_template
- | def_operand_types
- | def_operands
- | output_header
- | output_decoder
- | output_exec
- | global_let'''
- t[0] = t[1]
-
-# Output blocks 'output <foo> {{...}}' (C++ code blocks) are copied
-# directly to the appropriate output section.
-
-
-# Protect any non-dict-substitution '%'s in a format string
-# (i.e. those not followed by '(')
-def protect_non_subst_percents(s):
- return re.sub(r'%(?!\()', '%%', s)
-
-# Massage output block by substituting in template definitions and bit
-# operators. We handle '%'s embedded in the string that don't
-# indicate template substitutions (or CPU-specific symbols, which get
-# handled in GenCode) by doubling them first so that the format
-# operation will reduce them back to single '%'s.
-def process_output(s):
- s = protect_non_subst_percents(s)
- # protects cpu-specific symbols too
- s = protect_cpu_symbols(s)
- return substBitOps(s % templateMap)
-
-def p_output_header(t):
- 'output_header : OUTPUT HEADER CODELIT SEMI'
- t[0] = GenCode(header_output = process_output(t[3]))
-
-def p_output_decoder(t):
- 'output_decoder : OUTPUT DECODER CODELIT SEMI'
- t[0] = GenCode(decoder_output = process_output(t[3]))
-
-def p_output_exec(t):
- 'output_exec : OUTPUT EXEC CODELIT SEMI'
- t[0] = GenCode(exec_output = process_output(t[3]))
-
-# global let blocks 'let {{...}}' (Python code blocks) are executed
-# directly when seen. Note that these execute in a special variable
-# context 'exportContext' to prevent the code from polluting this
-# script's namespace.
-def p_global_let(t):
- 'global_let : LET CODELIT SEMI'
- updateExportContext()
- exportContext["header_output"] = ''
- exportContext["decoder_output"] = ''
- exportContext["exec_output"] = ''
- exportContext["decode_block"] = ''
- try:
- exec fixPythonIndentation(t[2]) in exportContext
- except Exception, exc:
- error(t.lexer.lineno,
- 'error: %s in global let block "%s".' % (exc, t[2]))
- t[0] = GenCode(header_output = exportContext["header_output"],
- decoder_output = exportContext["decoder_output"],
- exec_output = exportContext["exec_output"],
- decode_block = exportContext["decode_block"])
-
-# Define the mapping from operand type extensions to C++ types and bit
-# widths (stored in operandTypeMap).
-def p_def_operand_types(t):
- 'def_operand_types : DEF OPERAND_TYPES CODELIT SEMI'
- try:
- userDict = eval('{' + t[3] + '}')
- except Exception, exc:
- error(t.lexer.lineno,
- 'error: %s in def operand_types block "%s".' % (exc, t[3]))
- buildOperandTypeMap(userDict, t.lexer.lineno)
- t[0] = GenCode() # contributes nothing to the output C++ file
-
-# Define the mapping from operand names to operand classes and other
-# traits. Stored in operandNameMap.
-def p_def_operands(t):
- 'def_operands : DEF OPERANDS CODELIT SEMI'
- if not globals().has_key('operandTypeMap'):
- error(t.lexer.lineno,
- 'error: operand types must be defined before operands')
- try:
- userDict = eval('{' + t[3] + '}', exportContext)
- except Exception, exc:
- error(t.lexer.lineno,
- 'error: %s in def operands block "%s".' % (exc, t[3]))
- buildOperandNameMap(userDict, t.lexer.lineno)
- t[0] = GenCode() # contributes nothing to the output C++ file
-
-# A bitfield definition looks like:
-# 'def [signed] bitfield <ID> [<first>:<last>]'
-# This generates a preprocessor macro in the output file.
-def p_def_bitfield_0(t):
- 'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT COLON INTLIT GREATER SEMI'
- expr = 'bits(machInst, %2d, %2d)' % (t[6], t[8])
- if (t[2] == 'signed'):
- expr = 'sext<%d>(%s)' % (t[6] - t[8] + 1, expr)
- hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr)
- t[0] = GenCode(header_output = hash_define)
-
-# alternate form for single bit: 'def [signed] bitfield <ID> [<bit>]'
-def p_def_bitfield_1(t):
- 'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT GREATER SEMI'
- expr = 'bits(machInst, %2d, %2d)' % (t[6], t[6])
- if (t[2] == 'signed'):
- expr = 'sext<%d>(%s)' % (1, expr)
- hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr)
- t[0] = GenCode(header_output = hash_define)
-
-# alternate form for structure member: 'def bitfield <ID> <ID>'
-def p_def_bitfield_struct(t):
- 'def_bitfield_struct : DEF opt_signed BITFIELD ID id_with_dot SEMI'
- if (t[2] != ''):
- error(t.lexer.lineno, 'error: structure bitfields are always unsigned.')
- expr = 'machInst.%s' % t[5]
- hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr)
- t[0] = GenCode(header_output = hash_define)
-
-def p_id_with_dot_0(t):
- 'id_with_dot : ID'
- t[0] = t[1]
-
-def p_id_with_dot_1(t):
- 'id_with_dot : ID DOT id_with_dot'
- t[0] = t[1] + t[2] + t[3]
-
-def p_opt_signed_0(t):
- 'opt_signed : SIGNED'
- t[0] = t[1]
-
-def p_opt_signed_1(t):
- 'opt_signed : empty'
- t[0] = ''
-
-# Global map variable to hold templates
-templateMap = {}
-
-def p_def_template(t):
- 'def_template : DEF TEMPLATE ID CODELIT SEMI'
- templateMap[t[3]] = Template(t[4])
- t[0] = GenCode()
-
-# An instruction format definition looks like
-# "def format <fmt>(<params>) {{...}};"
-def p_def_format(t):
- 'def_format : DEF FORMAT ID LPAREN param_list RPAREN CODELIT SEMI'
- (id, params, code) = (t[3], t[5], t[7])
- defFormat(id, params, code, t.lexer.lineno)
- t[0] = GenCode()
-
-# The formal parameter list for an instruction format is a possibly
-# empty list of comma-separated parameters. Positional (standard,
-# non-keyword) parameters must come first, followed by keyword
-# parameters, followed by a '*foo' parameter that gets excess
-# positional arguments (as in Python). Each of these three parameter
-# categories is optional.
-#
-# Note that we do not support the '**foo' parameter for collecting
-# otherwise undefined keyword args. Otherwise the parameter list is
-# (I believe) identical to what is supported in Python.
-#
-# The param list generates a tuple, where the first element is a list of
-# the positional params and the second element is a dict containing the
-# keyword params.
-def p_param_list_0(t):
- 'param_list : positional_param_list COMMA nonpositional_param_list'
- t[0] = t[1] + t[3]
-
-def p_param_list_1(t):
- '''param_list : positional_param_list
- | nonpositional_param_list'''
- t[0] = t[1]
-
-def p_positional_param_list_0(t):
- 'positional_param_list : empty'
- t[0] = []
-
-def p_positional_param_list_1(t):
- 'positional_param_list : ID'
- t[0] = [t[1]]
-
-def p_positional_param_list_2(t):
- 'positional_param_list : positional_param_list COMMA ID'
- t[0] = t[1] + [t[3]]
-
-def p_nonpositional_param_list_0(t):
- 'nonpositional_param_list : keyword_param_list COMMA excess_args_param'
- t[0] = t[1] + t[3]
-
-def p_nonpositional_param_list_1(t):
- '''nonpositional_param_list : keyword_param_list
- | excess_args_param'''
- t[0] = t[1]
-
-def p_keyword_param_list_0(t):
- 'keyword_param_list : keyword_param'
- t[0] = [t[1]]
-
-def p_keyword_param_list_1(t):
- 'keyword_param_list : keyword_param_list COMMA keyword_param'
- t[0] = t[1] + [t[3]]
-
-def p_keyword_param(t):
- 'keyword_param : ID EQUALS expr'
- t[0] = t[1] + ' = ' + t[3].__repr__()
-
-def p_excess_args_param(t):
- 'excess_args_param : ASTERISK ID'
- # Just concatenate them: '*ID'. Wrap in list to be consistent
- # with positional_param_list and keyword_param_list.
- t[0] = [t[1] + t[2]]
-
-# End of format definition-related rules.
-##############
-
-#
-# A decode block looks like:
-# decode <field1> [, <field2>]* [default <inst>] { ... }
-#
-def p_decode_block(t):
- 'decode_block : DECODE ID opt_default LBRACE decode_stmt_list RBRACE'
- default_defaults = defaultStack.pop()
- codeObj = t[5]
- # use the "default defaults" only if there was no explicit
- # default statement in decode_stmt_list
- if not codeObj.has_decode_default:
- codeObj += default_defaults
- codeObj.wrap_decode_block('switch (%s) {\n' % t[2], '}\n')
- t[0] = codeObj
-
-# The opt_default statement serves only to push the "default defaults"
-# onto defaultStack. This value will be used by nested decode blocks,
-# and used and popped off when the current decode_block is processed
-# (in p_decode_block() above).
-def p_opt_default_0(t):
- 'opt_default : empty'
- # no default specified: reuse the one currently at the top of the stack
- defaultStack.push(defaultStack.top())
- # no meaningful value returned
- t[0] = None
-
-def p_opt_default_1(t):
- 'opt_default : DEFAULT inst'
- # push the new default
- codeObj = t[2]
- codeObj.wrap_decode_block('\ndefault:\n', 'break;\n')
- defaultStack.push(codeObj)
- # no meaningful value returned
- t[0] = None
-
-def p_decode_stmt_list_0(t):
- 'decode_stmt_list : decode_stmt'
- t[0] = t[1]
-
-def p_decode_stmt_list_1(t):
- 'decode_stmt_list : decode_stmt decode_stmt_list'
- if (t[1].has_decode_default and t[2].has_decode_default):
- error(t.lexer.lineno, 'Two default cases in decode block')
- t[0] = t[1] + t[2]
-
-#
-# Decode statement rules
-#
-# There are four types of statements allowed in a decode block:
-# 1. Format blocks 'format <foo> { ... }'
-# 2. Nested decode blocks
-# 3. Instruction definitions.
-# 4. C preprocessor directives.
-
-
-# Preprocessor directives found in a decode statement list are passed
-# through to the output, replicated to all of the output code
-# streams. This works well for ifdefs, so we can ifdef out both the
-# declarations and the decode cases generated by an instruction
-# definition. Handling them as part of the grammar makes it easy to
-# keep them in the right place with respect to the code generated by
-# the other statements.
-def p_decode_stmt_cpp(t):
- 'decode_stmt : CPPDIRECTIVE'
- t[0] = GenCode(t[1], t[1], t[1], t[1])
-
-# A format block 'format <foo> { ... }' sets the default instruction
-# format used to handle instruction definitions inside the block.
-# This format can be overridden by using an explicit format on the
-# instruction definition or with a nested format block.
-def p_decode_stmt_format(t):
- 'decode_stmt : FORMAT push_format_id LBRACE decode_stmt_list RBRACE'
- # The format will be pushed on the stack when 'push_format_id' is
- # processed (see below). Once the parser has recognized the full
- # production (though the right brace), we're done with the format,
- # so now we can pop it.
- formatStack.pop()
- t[0] = t[4]
-
-# This rule exists so we can set the current format (& push the stack)
-# when we recognize the format name part of the format block.
-def p_push_format_id(t):
- 'push_format_id : ID'
- try:
- formatStack.push(formatMap[t[1]])
- t[0] = ('', '// format %s' % t[1])
- except KeyError:
- error(t.lexer.lineno, 'instruction format "%s" not defined.' % t[1])
-
-# Nested decode block: if the value of the current field matches the
-# specified constant, do a nested decode on some other field.
-def p_decode_stmt_decode(t):
- 'decode_stmt : case_label COLON decode_block'
- label = t[1]
- codeObj = t[3]
- # just wrap the decoding code from the block as a case in the
- # outer switch statement.
- codeObj.wrap_decode_block('\n%s:\n' % label)
- codeObj.has_decode_default = (label == 'default')
- t[0] = codeObj
-
-# Instruction definition (finally!).
-def p_decode_stmt_inst(t):
- 'decode_stmt : case_label COLON inst SEMI'
- label = t[1]
- codeObj = t[3]
- codeObj.wrap_decode_block('\n%s:' % label, 'break;\n')
- codeObj.has_decode_default = (label == 'default')
- t[0] = codeObj
-
-# The case label is either a list of one or more constants or 'default'
-def p_case_label_0(t):
- 'case_label : intlit_list'
- t[0] = ': '.join(map(lambda a: 'case %#x' % a, t[1]))
-
-def p_case_label_1(t):
- 'case_label : DEFAULT'
- t[0] = 'default'
-
-#
-# The constant list for a decode case label must be non-empty, but may have
-# one or more comma-separated integer literals in it.
-#
-def p_intlit_list_0(t):
- 'intlit_list : INTLIT'
- t[0] = [t[1]]
-
-def p_intlit_list_1(t):
- 'intlit_list : intlit_list COMMA INTLIT'
- t[0] = t[1]
- t[0].append(t[3])
-
-# Define an instruction using the current instruction format (specified
-# by an enclosing format block).
-# "<mnemonic>(<args>)"
-def p_inst_0(t):
- 'inst : ID LPAREN arg_list RPAREN'
- # Pass the ID and arg list to the current format class to deal with.
- currentFormat = formatStack.top()
- codeObj = currentFormat.defineInst(t[1], t[3], t.lexer.lineno)
- args = ','.join(map(str, t[3]))
- args = re.sub('(?m)^', '//', args)
- args = re.sub('^//', '', args)
- comment = '\n// %s::%s(%s)\n' % (currentFormat.id, t[1], args)
- codeObj.prepend_all(comment)
- t[0] = codeObj
-
-# Define an instruction using an explicitly specified format:
-# "<fmt>::<mnemonic>(<args>)"
-def p_inst_1(t):
- 'inst : ID DBLCOLON ID LPAREN arg_list RPAREN'
- try:
- format = formatMap[t[1]]
- except KeyError:
- error(t.lexer.lineno, 'instruction format "%s" not defined.' % t[1])
- codeObj = format.defineInst(t[3], t[5], t.lexer.lineno)
- comment = '\n// %s::%s(%s)\n' % (t[1], t[3], t[5])
- codeObj.prepend_all(comment)
- t[0] = codeObj
-
-# The arg list generates a tuple, where the first element is a list of
-# the positional args and the second element is a dict containing the
-# keyword args.
-def p_arg_list_0(t):
- 'arg_list : positional_arg_list COMMA keyword_arg_list'
- t[0] = ( t[1], t[3] )
-
-def p_arg_list_1(t):
- 'arg_list : positional_arg_list'
- t[0] = ( t[1], {} )
-
-def p_arg_list_2(t):
- 'arg_list : keyword_arg_list'
- t[0] = ( [], t[1] )
-
-def p_positional_arg_list_0(t):
- 'positional_arg_list : empty'
- t[0] = []
-
-def p_positional_arg_list_1(t):
- 'positional_arg_list : expr'
- t[0] = [t[1]]
-
-def p_positional_arg_list_2(t):
- 'positional_arg_list : positional_arg_list COMMA expr'
- t[0] = t[1] + [t[3]]
-
-def p_keyword_arg_list_0(t):
- 'keyword_arg_list : keyword_arg'
- t[0] = t[1]
-
-def p_keyword_arg_list_1(t):
- 'keyword_arg_list : keyword_arg_list COMMA keyword_arg'
- t[0] = t[1]
- t[0].update(t[3])
-
-def p_keyword_arg(t):
- 'keyword_arg : ID EQUALS expr'
- t[0] = { t[1] : t[3] }
-
-#
-# Basic expressions. These constitute the argument values of
-# "function calls" (i.e. instruction definitions in the decode block)
-# and default values for formal parameters of format functions.
-#
-# Right now, these are either strings, integers, or (recursively)
-# lists of exprs (using Python square-bracket list syntax). Note that
-# bare identifiers are trated as string constants here (since there
-# isn't really a variable namespace to refer to).
-#
-def p_expr_0(t):
- '''expr : ID
- | INTLIT
- | STRLIT
- | CODELIT'''
- t[0] = t[1]
-
-def p_expr_1(t):
- '''expr : LBRACKET list_expr RBRACKET'''
- t[0] = t[2]
-
-def p_list_expr_0(t):
- 'list_expr : expr'
- t[0] = [t[1]]
-
-def p_list_expr_1(t):
- 'list_expr : list_expr COMMA expr'
- t[0] = t[1] + [t[3]]
-
-def p_list_expr_2(t):
- 'list_expr : empty'
- t[0] = []
+ # both the latter output blocks and the decode block are in
+ # the namespace
+ namespace_code = t[3] + t[4]
+ # pass it all back to the caller of yacc.parse()
+ t[0] = (isa_name, namespace, global_code, namespace_code)
+
+ # ISA name declaration looks like "namespace <foo>;"
+ def p_name_decl(self, t):
+ 'name_decl : NAMESPACE ID SEMI'
+ t[0] = t[2]
+
+ # 'opt_defs_and_outputs' is a possibly empty sequence of
+ # def and/or output statements.
+ def p_opt_defs_and_outputs_0(self, t):
+ 'opt_defs_and_outputs : empty'
+ t[0] = GenCode()
+
+ def p_opt_defs_and_outputs_1(self, t):
+ 'opt_defs_and_outputs : defs_and_outputs'
+ t[0] = t[1]
+
+ def p_defs_and_outputs_0(self, t):
+ 'defs_and_outputs : def_or_output'
+ t[0] = t[1]
+
+ def p_defs_and_outputs_1(self, t):
+ 'defs_and_outputs : defs_and_outputs def_or_output'
+ t[0] = t[1] + t[2]
+
+ # The list of possible definition/output statements.
+ def p_def_or_output(self, t):
+ '''def_or_output : def_format
+ | def_bitfield
+ | def_bitfield_struct
+ | def_template
+ | def_operand_types
+ | def_operands
+ | output_header
+ | output_decoder
+ | output_exec
+ | global_let'''
+ t[0] = t[1]
+
+ # Output blocks 'output <foo> {{...}}' (C++ code blocks) are copied
+ # directly to the appropriate output section.
+
+ # Massage output block by substituting in template definitions and
+ # bit operators. We handle '%'s embedded in the string that don't
+ # indicate template substitutions (or CPU-specific symbols, which
+ # get handled in GenCode) by doubling them first so that the
+ # format operation will reduce them back to single '%'s.
+ def process_output(self, s):
+ s = protect_non_subst_percents(s)
+ # protects cpu-specific symbols too
+ s = protect_cpu_symbols(s)
+ return substBitOps(s % self.templateMap)
+
+ def p_output_header(self, t):
+ 'output_header : OUTPUT HEADER CODELIT SEMI'
+ t[0] = GenCode(header_output = self.process_output(t[3]))
+
+ def p_output_decoder(self, t):
+ 'output_decoder : OUTPUT DECODER CODELIT SEMI'
+ t[0] = GenCode(decoder_output = self.process_output(t[3]))
+
+ def p_output_exec(self, t):
+ 'output_exec : OUTPUT EXEC CODELIT SEMI'
+ t[0] = GenCode(exec_output = self.process_output(t[3]))
+
+ # global let blocks 'let {{...}}' (Python code blocks) are
+ # executed directly when seen. Note that these execute in a
+ # special variable context 'exportContext' to prevent the code
+ # from polluting this script's namespace.
+ def p_global_let(self, t):
+ 'global_let : LET CODELIT SEMI'
+ updateExportContext()
+ exportContext["header_output"] = ''
+ exportContext["decoder_output"] = ''
+ exportContext["exec_output"] = ''
+ exportContext["decode_block"] = ''
+ try:
+ exec fixPythonIndentation(t[2]) in exportContext
+ except Exception, exc:
+ error(t.lexer.lineno,
+ 'error: %s in global let block "%s".' % (exc, t[2]))
+ t[0] = GenCode(header_output = exportContext["header_output"],
+ decoder_output = exportContext["decoder_output"],
+ exec_output = exportContext["exec_output"],
+ decode_block = exportContext["decode_block"])
+
+ # Define the mapping from operand type extensions to C++ types and
+ # bit widths (stored in operandTypeMap).
+ def p_def_operand_types(self, t):
+ 'def_operand_types : DEF OPERAND_TYPES CODELIT SEMI'
+ try:
+ userDict = eval('{' + t[3] + '}')
+ except Exception, exc:
+ error(t.lexer.lineno,
+ 'error: %s in def operand_types block "%s".' % (exc, t[3]))
+ buildOperandTypeMap(userDict, t.lexer.lineno)
+ t[0] = GenCode() # contributes nothing to the output C++ file
+
+ # Define the mapping from operand names to operand classes and
+ # other traits. Stored in operandNameMap.
+ def p_def_operands(self, t):
+ 'def_operands : DEF OPERANDS CODELIT SEMI'
+ if not globals().has_key('operandTypeMap'):
+ error(t.lexer.lineno,
+ 'error: operand types must be defined before operands')
+ try:
+ userDict = eval('{' + t[3] + '}', exportContext)
+ except Exception, exc:
+ error(t.lexer.lineno,
+ 'error: %s in def operands block "%s".' % (exc, t[3]))
+ buildOperandNameMap(userDict, t.lexer.lineno)
+ t[0] = GenCode() # contributes nothing to the output C++ file
+
+ # A bitfield definition looks like:
+ # 'def [signed] bitfield <ID> [<first>:<last>]'
+ # This generates a preprocessor macro in the output file.
+ def p_def_bitfield_0(self, t):
+ 'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT COLON INTLIT GREATER SEMI'
+ expr = 'bits(machInst, %2d, %2d)' % (t[6], t[8])
+ if (t[2] == 'signed'):
+ expr = 'sext<%d>(%s)' % (t[6] - t[8] + 1, expr)
+ hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr)
+ t[0] = GenCode(header_output = hash_define)
+
+ # alternate form for single bit: 'def [signed] bitfield <ID> [<bit>]'
+ def p_def_bitfield_1(self, t):
+ 'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT GREATER SEMI'
+ expr = 'bits(machInst, %2d, %2d)' % (t[6], t[6])
+ if (t[2] == 'signed'):
+ expr = 'sext<%d>(%s)' % (1, expr)
+ hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr)
+ t[0] = GenCode(header_output = hash_define)
+
+ # alternate form for structure member: 'def bitfield <ID> <ID>'
+ def p_def_bitfield_struct(self, t):
+ 'def_bitfield_struct : DEF opt_signed BITFIELD ID id_with_dot SEMI'
+ if (t[2] != ''):
+ error(t.lexer.lineno,
+ 'error: structure bitfields are always unsigned.')
+ expr = 'machInst.%s' % t[5]
+ hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr)
+ t[0] = GenCode(header_output = hash_define)
+
+ def p_id_with_dot_0(self, t):
+ 'id_with_dot : ID'
+ t[0] = t[1]
+
+ def p_id_with_dot_1(self, t):
+ 'id_with_dot : ID DOT id_with_dot'
+ t[0] = t[1] + t[2] + t[3]
+
+ def p_opt_signed_0(self, t):
+ 'opt_signed : SIGNED'
+ t[0] = t[1]
+
+ def p_opt_signed_1(self, t):
+ 'opt_signed : empty'
+ t[0] = ''
+
+ def p_def_template(self, t):
+ 'def_template : DEF TEMPLATE ID CODELIT SEMI'
+ self.templateMap[t[3]] = Template(t[4])
+ t[0] = GenCode()
+
+ # An instruction format definition looks like
+ # "def format <fmt>(<params>) {{...}};"
+ def p_def_format(self, t):
+ 'def_format : DEF FORMAT ID LPAREN param_list RPAREN CODELIT SEMI'
+ (id, params, code) = (t[3], t[5], t[7])
+ defFormat(id, params, code, t.lexer.lineno)
+ t[0] = GenCode()
+
+ # The formal parameter list for an instruction format is a
+ # possibly empty list of comma-separated parameters. Positional
+ # (standard, non-keyword) parameters must come first, followed by
+ # keyword parameters, followed by a '*foo' parameter that gets
+ # excess positional arguments (as in Python). Each of these three
+ # parameter categories is optional.
+ #
+ # Note that we do not support the '**foo' parameter for collecting
+ # otherwise undefined keyword args. Otherwise the parameter list
+ # is (I believe) identical to what is supported in Python.
+ #
+ # The param list generates a tuple, where the first element is a
+ # list of the positional params and the second element is a dict
+ # containing the keyword params.
+ def p_param_list_0(self, t):
+ 'param_list : positional_param_list COMMA nonpositional_param_list'
+ t[0] = t[1] + t[3]
+
+ def p_param_list_1(self, t):
+ '''param_list : positional_param_list
+ | nonpositional_param_list'''
+ t[0] = t[1]
+
+ def p_positional_param_list_0(self, t):
+ 'positional_param_list : empty'
+ t[0] = []
+
+ def p_positional_param_list_1(self, t):
+ 'positional_param_list : ID'
+ t[0] = [t[1]]
+
+ def p_positional_param_list_2(self, t):
+ 'positional_param_list : positional_param_list COMMA ID'
+ t[0] = t[1] + [t[3]]
+
+ def p_nonpositional_param_list_0(self, t):
+ 'nonpositional_param_list : keyword_param_list COMMA excess_args_param'
+ t[0] = t[1] + t[3]
+
+ def p_nonpositional_param_list_1(self, t):
+ '''nonpositional_param_list : keyword_param_list
+ | excess_args_param'''
+ t[0] = t[1]
+
+ def p_keyword_param_list_0(self, t):
+ 'keyword_param_list : keyword_param'
+ t[0] = [t[1]]
+
+ def p_keyword_param_list_1(self, t):
+ 'keyword_param_list : keyword_param_list COMMA keyword_param'
+ t[0] = t[1] + [t[3]]
+
+ def p_keyword_param(self, t):
+ 'keyword_param : ID EQUALS expr'
+ t[0] = t[1] + ' = ' + t[3].__repr__()
+
+ def p_excess_args_param(self, t):
+ 'excess_args_param : ASTERISK ID'
+ # Just concatenate them: '*ID'. Wrap in list to be consistent
+ # with positional_param_list and keyword_param_list.
+ t[0] = [t[1] + t[2]]
+
+ # End of format definition-related rules.
+ ##############
+
+ #
+ # A decode block looks like:
+ # decode <field1> [, <field2>]* [default <inst>] { ... }
+ #
+ def p_decode_block(self, t):
+ 'decode_block : DECODE ID opt_default LBRACE decode_stmt_list RBRACE'
+ default_defaults = defaultStack.pop()
+ codeObj = t[5]
+ # use the "default defaults" only if there was no explicit
+ # default statement in decode_stmt_list
+ if not codeObj.has_decode_default:
+ codeObj += default_defaults
+ codeObj.wrap_decode_block('switch (%s) {\n' % t[2], '}\n')
+ t[0] = codeObj
+
+ # The opt_default statement serves only to push the "default
+ # defaults" onto defaultStack. This value will be used by nested
+ # decode blocks, and used and popped off when the current
+ # decode_block is processed (in p_decode_block() above).
+ def p_opt_default_0(self, t):
+ 'opt_default : empty'
+ # no default specified: reuse the one currently at the top of
+ # the stack
+ defaultStack.push(defaultStack.top())
+ # no meaningful value returned
+ t[0] = None
+
+ def p_opt_default_1(self, t):
+ 'opt_default : DEFAULT inst'
+ # push the new default
+ codeObj = t[2]
+ codeObj.wrap_decode_block('\ndefault:\n', 'break;\n')
+ defaultStack.push(codeObj)
+ # no meaningful value returned
+ t[0] = None
+
+ def p_decode_stmt_list_0(self, t):
+ 'decode_stmt_list : decode_stmt'
+ t[0] = t[1]
+
+ def p_decode_stmt_list_1(self, t):
+ 'decode_stmt_list : decode_stmt decode_stmt_list'
+ if (t[1].has_decode_default and t[2].has_decode_default):
+ error(t.lexer.lineno, 'Two default cases in decode block')
+ t[0] = t[1] + t[2]
+
+ #
+ # Decode statement rules
+ #
+ # There are four types of statements allowed in a decode block:
+ # 1. Format blocks 'format <foo> { ... }'
+ # 2. Nested decode blocks
+ # 3. Instruction definitions.
+ # 4. C preprocessor directives.
+
+
+ # Preprocessor directives found in a decode statement list are
+ # passed through to the output, replicated to all of the output
+ # code streams. This works well for ifdefs, so we can ifdef out
+ # both the declarations and the decode cases generated by an
+ # instruction definition. Handling them as part of the grammar
+ # makes it easy to keep them in the right place with respect to
+ # the code generated by the other statements.
+ def p_decode_stmt_cpp(self, t):
+ 'decode_stmt : CPPDIRECTIVE'
+ t[0] = GenCode(t[1], t[1], t[1], t[1])
+
+ # A format block 'format <foo> { ... }' sets the default
+ # instruction format used to handle instruction definitions inside
+ # the block. This format can be overridden by using an explicit
+ # format on the instruction definition or with a nested format
+ # block.
+ def p_decode_stmt_format(self, t):
+ 'decode_stmt : FORMAT push_format_id LBRACE decode_stmt_list RBRACE'
+ # The format will be pushed on the stack when 'push_format_id'
+ # is processed (see below). Once the parser has recognized
+ # the full production (though the right brace), we're done
+ # with the format, so now we can pop it.
+ formatStack.pop()
+ t[0] = t[4]
+
+ # This rule exists so we can set the current format (& push the
+ # stack) when we recognize the format name part of the format
+ # block.
+ def p_push_format_id(self, t):
+ 'push_format_id : ID'
+ try:
+ formatStack.push(formatMap[t[1]])
+ t[0] = ('', '// format %s' % t[1])
+ except KeyError:
+ error(t.lexer.lineno,
+ 'instruction format "%s" not defined.' % t[1])
+
+ # Nested decode block: if the value of the current field matches
+ # the specified constant, do a nested decode on some other field.
+ def p_decode_stmt_decode(self, t):
+ 'decode_stmt : case_label COLON decode_block'
+ label = t[1]
+ codeObj = t[3]
+ # just wrap the decoding code from the block as a case in the
+ # outer switch statement.
+ codeObj.wrap_decode_block('\n%s:\n' % label)
+ codeObj.has_decode_default = (label == 'default')
+ t[0] = codeObj
+
+ # Instruction definition (finally!).
+ def p_decode_stmt_inst(self, t):
+ 'decode_stmt : case_label COLON inst SEMI'
+ label = t[1]
+ codeObj = t[3]
+ codeObj.wrap_decode_block('\n%s:' % label, 'break;\n')
+ codeObj.has_decode_default = (label == 'default')
+ t[0] = codeObj
+
+ # The case label is either a list of one or more constants or
+ # 'default'
+ def p_case_label_0(self, t):
+ 'case_label : intlit_list'
+ def make_case(intlit):
+ if intlit >= 2**32:
+ return 'case ULL(%#x)' % intlit
+ else:
+ return 'case %#x' % intlit
+ t[0] = ': '.join(map(make_case, t[1]))
+
+ def p_case_label_1(self, t):
+ 'case_label : DEFAULT'
+ t[0] = 'default'
+
+ #
+ # The constant list for a decode case label must be non-empty, but
+ # may have one or more comma-separated integer literals in it.
+ #
+ def p_intlit_list_0(self, t):
+ 'intlit_list : INTLIT'
+ t[0] = [t[1]]
+
+ def p_intlit_list_1(self, t):
+ 'intlit_list : intlit_list COMMA INTLIT'
+ t[0] = t[1]
+ t[0].append(t[3])
+
+ # Define an instruction using the current instruction format
+ # (specified by an enclosing format block).
+ # "<mnemonic>(<args>)"
+ def p_inst_0(self, t):
+ 'inst : ID LPAREN arg_list RPAREN'
+ # Pass the ID and arg list to the current format class to deal with.
+ currentFormat = formatStack.top()
+ codeObj = currentFormat.defineInst(t[1], t[3], t.lexer.lineno)
+ args = ','.join(map(str, t[3]))
+ args = re.sub('(?m)^', '//', args)
+ args = re.sub('^//', '', args)
+ comment = '\n// %s::%s(%s)\n' % (currentFormat.id, t[1], args)
+ codeObj.prepend_all(comment)
+ t[0] = codeObj
+
+ # Define an instruction using an explicitly specified format:
+ # "<fmt>::<mnemonic>(<args>)"
+ def p_inst_1(self, t):
+ 'inst : ID DBLCOLON ID LPAREN arg_list RPAREN'
+ try:
+ format = formatMap[t[1]]
+ except KeyError:
+ error(t.lexer.lineno,
+ 'instruction format "%s" not defined.' % t[1])
+ codeObj = format.defineInst(t[3], t[5], t.lexer.lineno)
+ comment = '\n// %s::%s(%s)\n' % (t[1], t[3], t[5])
+ codeObj.prepend_all(comment)
+ t[0] = codeObj
+
+ # The arg list generates a tuple, where the first element is a
+ # list of the positional args and the second element is a dict
+ # containing the keyword args.
+ def p_arg_list_0(self, t):
+ 'arg_list : positional_arg_list COMMA keyword_arg_list'
+ t[0] = ( t[1], t[3] )
+
+ def p_arg_list_1(self, t):
+ 'arg_list : positional_arg_list'
+ t[0] = ( t[1], {} )
+
+ def p_arg_list_2(self, t):
+ 'arg_list : keyword_arg_list'
+ t[0] = ( [], t[1] )
+
+ def p_positional_arg_list_0(self, t):
+ 'positional_arg_list : empty'
+ t[0] = []
+
+ def p_positional_arg_list_1(self, t):
+ 'positional_arg_list : expr'
+ t[0] = [t[1]]
+
+ def p_positional_arg_list_2(self, t):
+ 'positional_arg_list : positional_arg_list COMMA expr'
+ t[0] = t[1] + [t[3]]
+
+ def p_keyword_arg_list_0(self, t):
+ 'keyword_arg_list : keyword_arg'
+ t[0] = t[1]
+
+ def p_keyword_arg_list_1(self, t):
+ 'keyword_arg_list : keyword_arg_list COMMA keyword_arg'
+ t[0] = t[1]
+ t[0].update(t[3])
+
+ def p_keyword_arg(self, t):
+ 'keyword_arg : ID EQUALS expr'
+ t[0] = { t[1] : t[3] }
+
+ #
+ # Basic expressions. These constitute the argument values of
+ # "function calls" (i.e. instruction definitions in the decode
+ # block) and default values for formal parameters of format
+ # functions.
+ #
+ # Right now, these are either strings, integers, or (recursively)
+ # lists of exprs (using Python square-bracket list syntax). Note
+ # that bare identifiers are trated as string constants here (since
+ # there isn't really a variable namespace to refer to).
+ #
+ def p_expr_0(self, t):
+ '''expr : ID
+ | INTLIT
+ | STRLIT
+ | CODELIT'''
+ t[0] = t[1]
+
+ def p_expr_1(self, t):
+ '''expr : LBRACKET list_expr RBRACKET'''
+ t[0] = t[2]
+
+ def p_list_expr_0(self, t):
+ 'list_expr : expr'
+ t[0] = [t[1]]
+
+ def p_list_expr_1(self, t):
+ 'list_expr : list_expr COMMA expr'
+ t[0] = t[1] + [t[3]]
+
+ def p_list_expr_2(self, t):
+ 'list_expr : empty'
+ t[0] = []
+
+ #
+ # Empty production... use in other rules for readability.
+ #
+ def p_empty(self, t):
+ 'empty :'
+ pass
+
+ # Parse error handler. Note that the argument here is the
+ # offending *token*, not a grammar symbol (hence the need to use
+ # t.value)
+ def p_error(self, t):
+ if t:
+ error(t.lexer.lineno, "syntax error at '%s'" % t.value)
+ else:
+ error(0, "unknown syntax error", True)
-#
-# Empty production... use in other rules for readability.
-#
-def p_empty(t):
- 'empty :'
- pass
-
-# Parse error handler. Note that the argument here is the offending
-# *token*, not a grammar symbol (hence the need to use t.value)
-def p_error(t):
- if t:
- error(t.lexer.lineno, "syntax error at '%s'" % t.value)
- else:
- error(0, "unknown syntax error", True)
+ # END OF GRAMMAR RULES
-# END OF GRAMMAR RULES
-#
# Now build the parser.
-parser = yacc.yacc()
-
+parser = ISAParser()
#####################################################################
#
@@ -766,6 +768,11 @@ def expand_cpu_symbols_to_string(template):
def protect_cpu_symbols(template):
return re.sub(r'%(?=\(CPU_)', '%%', template)
+# Protect any non-dict-substitution '%'s in a format string
+# (i.e. those not followed by '(')
+def protect_non_subst_percents(s):
+ return re.sub(r'%(?!\()', '%%', s)
+
###############
# GenCode class
#
@@ -839,7 +846,7 @@ exportContext = {}
def updateExportContext():
exportContext.update(exportDict(*exportContextSymbols))
- exportContext.update(templateMap)
+ exportContext.update(parser.templateMap)
def exportDict(*symNames):
return dict([(s, eval(s)) for s in symNames])
@@ -1049,7 +1056,7 @@ class Template:
# Build a dict ('myDict') to use for the template substitution.
# Start with the template namespace. Make a copy since we're
# going to modify it.
- myDict = templateMap.copy()
+ myDict = parser.templateMap.copy()
if isinstance(d, InstObjParams):
# If we're dealing with an InstObjParams object, we need
@@ -1463,6 +1470,16 @@ class MemOperand(Operand):
def makeAccSize(self):
return self.size
+class PCOperand(Operand):
+ def makeConstructor(self):
+ return ''
+
+ def makeRead(self):
+ return '%s = xc->readPC();\n' % self.base_name
+
+ def makeWrite(self):
+ return 'xc->setPC(%s);\n' % self.base_name
+
class UPCOperand(Operand):
def makeConstructor(self):
return ''
@@ -1975,8 +1992,7 @@ def parse_isa_desc(isa_desc_file, output_dir):
fileNameStack.push((isa_desc_file, 0))
# Parse it.
- (isa_name, namespace, global_code, namespace_code) = \
- parser.parse(isa_desc, lexer=lexer)
+ (isa_name, namespace, global_code, namespace_code) = parser.parse(isa_desc)
# grab the last three path components of isa_desc_file to put in
# the output
diff --git a/src/arch/micro_asm.py b/src/arch/micro_asm.py
index 3433a8076..4e5400cef 100644
--- a/src/arch/micro_asm.py
+++ b/src/arch/micro_asm.py
@@ -34,10 +34,6 @@ import traceback
# get type names
from types import *
-# Prepend the directory where the PLY lex & yacc modules are found
-# to the search path.
-sys.path[0:0] = [os.environ['M5_PLY']]
-
from ply import lex
from ply import yacc
diff --git a/src/arch/mips/BISystem.py b/src/arch/mips/BISystem.py
index dd4e4fe25..a6e4091f2 100755
--- a/src/arch/mips/BISystem.py
+++ b/src/arch/mips/BISystem.py
@@ -28,10 +28,11 @@
#
# Authors: Jaidev Patwardhan
-from m5 import build_env
+from m5.defines import buildEnv
+
from System import *
-if build_env['FULL_SYSTEM']:
+if buildEnv['FULL_SYSTEM']:
class BareIronMipsSystem(MipsSystem):
type = 'BareIronMipsSystem'
system_type = 34
diff --git a/src/arch/mips/MipsCPU.py b/src/arch/mips/MipsCPU.py
index 81c6bdacf..48ee4171c 100644
--- a/src/arch/mips/MipsCPU.py
+++ b/src/arch/mips/MipsCPU.py
@@ -29,12 +29,13 @@
# Authors: Jaidev Patwardhan
# Korey Sewell
-from m5.SimObject import SimObject
+from m5.defines import buildEnv
from m5.params import *
+
from BaseCPU import BaseCPU
class BaseMipsCPU(BaseCPU)
- if build_env['TARGET_ISA'] == 'mips':
+ if buildEnv['TARGET_ISA'] == 'mips':
CP0_IntCtl_IPTI = Param.Unsigned(0,"No Description")
CP0_IntCtl_IPPCI = Param.Unsigned(0,"No Description")
CP0_SrsCtl_HSS = Param.Unsigned(0,"No Description")
diff --git a/src/arch/mips/MipsSystem.py b/src/arch/mips/MipsSystem.py
index c3dcf4e0b..d271bd387 100644
--- a/src/arch/mips/MipsSystem.py
+++ b/src/arch/mips/MipsSystem.py
@@ -28,10 +28,10 @@
#
# Authors: Jaidev Patwardhan
-from m5.SimObject import SimObject
+from m5.defines import buildEnv
from m5.params import *
from m5.proxy import *
-from m5 import build_env
+
from System import System
class MipsSystem(System):
@@ -42,7 +42,7 @@ class MipsSystem(System):
system_type = Param.UInt64("Type of system we are emulating")
system_rev = Param.UInt64("Revision of system we are emulating")
-if build_env['FULL_SYSTEM']:
+if buildEnv['FULL_SYSTEM']:
class LinuxMipsSystem(MipsSystem):
type = 'LinuxMipsSystem'
system_type = 34
diff --git a/src/arch/mips/dsp.cc b/src/arch/mips/dsp.cc
index 6e4f7afea..b8b02ae9e 100755
--- a/src/arch/mips/dsp.cc
+++ b/src/arch/mips/dsp.cc
@@ -463,6 +463,8 @@ MipsISA::dspMuleq(int32_t a, int32_t b, int32_t mode, uint32_t *dspctl)
uint64_t b_values[SIMD_MAX_VALS];
uint64_t c_values[SIMD_MAX_VALS];
+ memset(c_values, 0, sizeof(c_values));
+
simdUnpack(a, a_values, SIMD_FMT_PH, SIGNED);
simdUnpack(b, b_values, SIMD_FMT_PH, SIGNED);
@@ -743,7 +745,7 @@ MipsISA::dspMulsaq(int64_t dspac, int32_t a, int32_t b, int32_t ac,
int nvals = SIMD_NVALS[fmt];
uint64_t a_values[SIMD_MAX_VALS];
uint64_t b_values[SIMD_MAX_VALS];
- int64_t temp[2];
+ int64_t temp[2] = {0, 0};
uint32_t ouflag = 0;
simdUnpack(a, a_values, fmt, SIGNED);
diff --git a/src/arch/mips/isa.hh b/src/arch/mips/isa.hh
index 15c043dc0..165adff83 100644
--- a/src/arch/mips/isa.hh
+++ b/src/arch/mips/isa.hh
@@ -172,8 +172,11 @@ namespace MipsISA
return reg;
}
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string &section);
+ void serialize(EventManager *em, std::ostream &os)
+ {}
+ void unserialize(EventManager *em, Checkpoint *cp,
+ const std::string &section)
+ {}
};
}
diff --git a/src/arch/mips/isa/formats/mem.isa b/src/arch/mips/isa/formats/mem.isa
index adcb16137..161a52b06 100644
--- a/src/arch/mips/isa/formats/mem.isa
+++ b/src/arch/mips/isa/formats/mem.isa
@@ -619,7 +619,7 @@ def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3;
def format Prefetch(ea_code = {{ EA = Rs + disp; }},
mem_flags = [], pf_flags = [], inst_flags = []) {{
- pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
+ pf_mem_flags = mem_flags + pf_flags + ['PREFETCH']
pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
'IsDataPrefetch', 'MemReadOp']
diff --git a/src/arch/mips/linux/linux.hh b/src/arch/mips/linux/linux.hh
index ee81fa18f..a2418cfb6 100644
--- a/src/arch/mips/linux/linux.hh
+++ b/src/arch/mips/linux/linux.hh
@@ -100,6 +100,7 @@ class MipsLinux : public Linux
static const unsigned TIOCISATTY_ = 0x5480;
static const unsigned TIOCGETS_ = 0x540d;
static const unsigned TIOCGETA_ = 0x7417;
+ static const unsigned TCSETAW_ = 0x5403; // 2.6.15 kernel
//@}
/// For table().
@@ -126,6 +127,22 @@ class MipsLinux : public Linux
/// assign themselves to process IDs reserved for
/// the root users.
static const int NUM_ROOT_PROCS = 2;
+
+ typedef struct {
+ int32_t uptime; /* Seconds since boot */
+ uint32_t loads[3]; /* 1, 5, and 15 minute load averages */
+ uint32_t totalram; /* Total usable main memory size */
+ uint32_t freeram; /* Available memory size */
+ uint32_t sharedram; /* Amount of shared memory */
+ uint32_t bufferram; /* Memory used by buffers */
+ uint32_t totalswap; /* Total swap space size */
+ uint32_t freeswap; /* swap space still available */
+ uint16_t procs; /* Number of current processes */
+ uint32_t totalhigh; /* Total high memory size */
+ uint32_t freehigh; /* Available high memory size */
+ uint32_t mem_unit; /* Memory unit size in bytes */
+ } tgt_sysinfo;
+
};
#endif
diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc
index 53a24487f..c2a05b73b 100644
--- a/src/arch/mips/linux/process.cc
+++ b/src/arch/mips/linux/process.cc
@@ -51,7 +51,8 @@ static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
+ int index = 0;
+ TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, index));
strcpy(name->sysname, "Linux");
strcpy(name->nodename,"m5.eecs.umich.edu");
@@ -70,14 +71,16 @@ static SyscallReturn
sys_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- unsigned op = process->getSyscallArg(tc, 0);
- // unsigned nbytes = process->getSyscallArg(tc, 2);
+ int index = 0;
+ unsigned op = process->getSyscallArg(tc, index);
+ unsigned bufPtr = process->getSyscallArg(tc, index);
+ // unsigned nbytes = process->getSyscallArg(tc, index);
switch (op) {
case 45:
{
// GSI_IEEE_FP_CONTROL
- TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1));
+ TypedBufferArg<uint64_t> fpcr(bufPtr);
// I don't think this exactly matches the HW FPCR
*fpcr = 0;
fpcr.copyOut(tc->getMemPort());
@@ -97,15 +100,17 @@ static SyscallReturn
sys_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- unsigned op = process->getSyscallArg(tc, 0);
- // unsigned nbytes = process->getSyscallArg(tc, 2);
+ int index = 0;
+ unsigned op = process->getSyscallArg(tc, index);
+ Addr bufPtr = process->getSyscallArg(tc, index);
+ // unsigned nbytes = process->getSyscallArg(tc, index);
switch (op) {
case 14:
{
// SSI_IEEE_FP_CONTROL
- TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1));
+ TypedBufferArg<uint64_t> fpcr(bufPtr);
// I don't think this exactly matches the HW FPCR
fpcr.copyIn(tc->getMemPort());
DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): "
@@ -238,7 +243,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 113 */ SyscallDesc("vm86", unimplementedFunc),
/* 114 */ SyscallDesc("wait4", unimplementedFunc),
/* 115 */ SyscallDesc("swapoff", unimplementedFunc),
- /* 116 */ SyscallDesc("sysinfo", unimplementedFunc),
+ /* 116 */ SyscallDesc("sysinfo", sysinfoFunc<MipsLinux>),
/* 117 */ SyscallDesc("ipc", unimplementedFunc),
/* 118 */ SyscallDesc("fsync", unimplementedFunc),
/* 119 */ SyscallDesc("sigreturn", unimplementedFunc),
@@ -413,12 +418,6 @@ MipsLinuxProcess::MipsLinuxProcess(LiveProcessParams * params,
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
{ }
-void
-MipsLinuxProcess::startup()
-{
- MipsLiveProcess::argsInit(MachineBytes, VMPageSize);
-}
-
SyscallDesc*
MipsLinuxProcess::getDesc(int callnum)
{
diff --git a/src/arch/mips/linux/process.hh b/src/arch/mips/linux/process.hh
index 5afde2be1..8c45014e0 100644
--- a/src/arch/mips/linux/process.hh
+++ b/src/arch/mips/linux/process.hh
@@ -43,8 +43,6 @@ class MipsLinuxProcess : public MipsLiveProcess
/// Constructor.
MipsLinuxProcess(LiveProcessParams * params, ObjectFile *objFile);
- void startup();
-
virtual SyscallDesc* getDesc(int callnum);
/// The target system's hostname.
diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc
index 3e9fb7c20..d96b0c81c 100644
--- a/src/arch/mips/process.cc
+++ b/src/arch/mips/process.cc
@@ -32,9 +32,15 @@
#include "arch/mips/isa_traits.hh"
#include "arch/mips/process.hh"
+
#include "base/loader/object_file.hh"
#include "base/misc.hh"
#include "cpu/thread_context.hh"
+
+#include "mem/page_table.hh"
+
+#include "sim/process.hh"
+#include "sim/process_impl.hh"
#include "sim/system.hh"
using namespace std;
@@ -62,14 +68,89 @@ MipsLiveProcess::MipsLiveProcess(LiveProcessParams * params,
void
MipsLiveProcess::startup()
{
+ Process::startup();
+
argsInit(MachineBytes, VMPageSize);
}
+void
+MipsLiveProcess::argsInit(int intSize, int pageSize)
+{
+ // load object file into target memory
+ objFile->loadSections(initVirtMem);
+
+ // Calculate how much space we need for arg & env arrays.
+ int argv_array_size = intSize * (argv.size() + 1);
+ int envp_array_size = intSize * (envp.size() + 1);
+ int arg_data_size = 0;
+ for (vector<string>::size_type i = 0; i < argv.size(); ++i) {
+ arg_data_size += argv[i].size() + 1;
+ }
+ int env_data_size = 0;
+ for (vector<string>::size_type i = 0; i < envp.size(); ++i) {
+ env_data_size += envp[i].size() + 1;
+ }
+
+ int space_needed =
+ argv_array_size + envp_array_size + arg_data_size + env_data_size;
+ if (space_needed < 32*1024)
+ space_needed = 32*1024;
+
+ // set bottom of stack
+ stack_min = stack_base - space_needed;
+ // align it
+ stack_min = roundDown(stack_min, pageSize);
+ stack_size = stack_base - stack_min;
+ // map memory
+ pTable->allocate(stack_min, roundUp(stack_size, pageSize));
+
+ // map out initial stack contents
+ // ========
+ // NOTE: Using uint32_t hardcodes MIPS32 and not MIPS64
+ // even if MIPS64 was intended. This is because the
+ // copyStringArray function templates on the parameters.
+ // Elegant way to check intSize and vary between 32/64?
+ // ========
+ uint32_t argv_array_base = stack_min + intSize; // room for argc
+ uint32_t envp_array_base = argv_array_base + argv_array_size;
+ uint32_t arg_data_base = envp_array_base + envp_array_size;
+ uint32_t env_data_base = arg_data_base + arg_data_size;
+
+ // write contents to stack
+ uint32_t argc = argv.size();
+
+ if (intSize == 8)
+ argc = htog((uint64_t)argc);
+ else if (intSize == 4)
+ argc = htog((uint32_t)argc);
+ else
+ panic("Unknown int size");
+
+
+ initVirtMem->writeBlob(stack_min, (uint8_t*)&argc, intSize);
+
+ copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
+
+ copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
+
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
+
+ setSyscallArg(tc, 0, argc);
+ setSyscallArg(tc, 1, argv_array_base);
+ tc->setIntReg(StackPointerReg, stack_min);
+
+ Addr prog_entry = objFile->entryPoint();
+ tc->setPC(prog_entry);
+ tc->setNextPC(prog_entry + sizeof(MachInst));
+ tc->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
+}
+
+
MipsISA::IntReg
-MipsLiveProcess::getSyscallArg(ThreadContext *tc, int i)
+MipsLiveProcess::getSyscallArg(ThreadContext *tc, int &i)
{
assert(i < 6);
- return tc->readIntReg(FirstArgumentReg + i);
+ return tc->readIntReg(FirstArgumentReg + i++);
}
void
diff --git a/src/arch/mips/process.hh b/src/arch/mips/process.hh
index 87c62330f..f35ec8554 100644
--- a/src/arch/mips/process.hh
+++ b/src/arch/mips/process.hh
@@ -45,10 +45,12 @@ class MipsLiveProcess : public LiveProcess
protected:
MipsLiveProcess(LiveProcessParams * params, ObjectFile *objFile);
- virtual void startup();
+ void startup();
+
+ void argsInit(int intSize, int pageSize);
public:
- MipsISA::IntReg getSyscallArg(ThreadContext *tc, int i);
+ MipsISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
void setSyscallArg(ThreadContext *tc, int i, MipsISA::IntReg val);
void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
};
diff --git a/src/arch/power/PowerTLB.py b/src/arch/power/PowerTLB.py
new file mode 100644
index 000000000..36dff5333
--- /dev/null
+++ b/src/arch/power/PowerTLB.py
@@ -0,0 +1,37 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2009 The University of Edinburgh
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Timothy M. Jones
+
+from m5.SimObject import SimObject
+from m5.params import *
+
+class PowerTLB(SimObject):
+ type = 'PowerTLB'
+ cxx_class = 'PowerISA::TLB'
+ size = Param.Int(64, "TLB size")
diff --git a/src/arch/power/SConscript b/src/arch/power/SConscript
new file mode 100644
index 000000000..1fb36eaab
--- /dev/null
+++ b/src/arch/power/SConscript
@@ -0,0 +1,61 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2009 The University of Edinburgh
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Timothy M. Jones
+
+Import('*')
+
+if env['TARGET_ISA'] == 'power':
+# Workaround for bug in SCons version > 0.97d20071212
+# Scons bug id: 2006 M5 Bug id: 308
+ Dir('isa/formats')
+ Source('insts/branch.cc')
+ Source('insts/mem.cc')
+ Source('insts/integer.cc')
+ Source('insts/floating.cc')
+ Source('insts/condition.cc')
+ Source('insts/static_inst.cc')
+ Source('pagetable.cc')
+ Source('tlb.cc')
+
+ SimObject('PowerTLB.py')
+ TraceFlag('Power')
+
+ if not env['FULL_SYSTEM']:
+ Source('process.cc')
+ Source('linux/linux.cc')
+ Source('linux/process.cc')
+
+ # Add in files generated by the ISA description.
+ isa_desc_files = env.ISADesc('isa/main.isa')
+
+ # Only non-header files need to be compiled.
+ for f in isa_desc_files:
+ if not f.path.endswith('.hh'):
+ Source(f)
+
diff --git a/src/arch/power/SConsopts b/src/arch/power/SConsopts
new file mode 100644
index 000000000..d762c2d58
--- /dev/null
+++ b/src/arch/power/SConsopts
@@ -0,0 +1,33 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2009 The University of Edinburgh
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Timothy M. Jones
+
+Import('*')
+
+all_isa_list.append('power')
diff --git a/src/mem/slicc/symbols/Symbol.cc b/src/arch/power/faults.hh
index 25af5ad47..eadcb7900 100644
--- a/src/mem/slicc/symbols/Symbol.cc
+++ b/src/arch/power/faults.hh
@@ -1,6 +1,6 @@
-
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * Copyright (c) 2009 The University of Edinburgh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,48 +25,63 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
*
+ * Authors: Gabe Black
+ * Timothy M. Jones
*/
-#include "mem/slicc/symbols/Symbol.hh"
+#ifndef __ARCH_POWER_FAULTS_HH__
+#define __ARCH_POWER_FAULTS_HH__
+
+#include "sim/faults.hh"
-Symbol::Symbol(string id, const Location& location, const Map<string, string>& pairs)
+namespace PowerISA
{
- m_id = id;
- m_location = location;
- m_pairs = pairs;
- if (!existPair("short")) {
- addPair("short", m_id);
- }
- m_used = false;
-}
-Symbol::Symbol(string id, const Location& location)
+class PowerFault : public FaultBase
{
- m_id = id;
- m_location = location;
- if (!existPair("short")) {
- addPair("short", m_id);
- }
- m_used = false;
-}
+ protected:
+ FaultName _name;
+
+ PowerFault(FaultName name)
+ : _name(name)
+ {
+ }
+
+ FaultName
+ name() const
+ {
+ return _name;
+ }
+};
-const string& Symbol::lookupPair(const string& key) const
+
+class UnimplementedOpcodeFault : public PowerFault
{
- if (!existPair(key)) {
- error("Value for pair '" + key + "' missing.");
- }
- return m_pairs.lookup(key);
-}
+ public:
+ UnimplementedOpcodeFault()
+ : PowerFault("Unimplemented Opcode")
+ {
+ }
+};
+
+
+class MachineCheckFault : public PowerFault
+{
+ public:
+ MachineCheckFault()
+ : PowerFault("Machine Check")
+ {
+ }
+};
+
-void Symbol::addPair(const string& key, const string& value)
+static inline Fault
+genMachineCheckFault()
{
- if (existPair(key)) {
- warning("Pair key '" + key + "' re-defined. new: '" + value + "' old: '" + lookupPair(key) + "'");
- }
- m_pairs.add(key, value);
+ return new MachineCheckFault();
}
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_FAULTS_HH__
diff --git a/src/arch/power/insts/branch.cc b/src/arch/power/insts/branch.cc
new file mode 100644
index 000000000..3f4346c97
--- /dev/null
+++ b/src/arch/power/insts/branch.cc
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2009 The University of Edinburgh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Timothy M. Jones
+ */
+
+#include "arch/power/insts/branch.hh"
+#include "base/loader/symtab.hh"
+
+using namespace PowerISA;
+
+const std::string &
+PCDependentDisassembly::disassemble(Addr pc, const SymbolTable *symtab) const
+{
+ if (!cachedDisassembly ||
+ pc != cachedPC || symtab != cachedSymtab)
+ {
+ if (cachedDisassembly)
+ delete cachedDisassembly;
+
+ cachedDisassembly =
+ new std::string(generateDisassembly(pc, symtab));
+ cachedPC = pc;
+ cachedSymtab = symtab;
+ }
+
+ return *cachedDisassembly;
+}
+
+Addr
+BranchPCRel::branchTarget(Addr pc) const
+{
+ return (uint32_t)(pc + disp);
+}
+
+std::string
+BranchPCRel::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ Addr target = pc + disp;
+
+ std::string str;
+ if (symtab && symtab->findSymbol(target, str))
+ ss << str;
+ else
+ ccprintf(ss, "0x%x", target);
+
+ return ss.str();
+}
+
+Addr
+BranchNonPCRel::branchTarget(Addr pc) const
+{
+ return targetAddr;
+}
+
+std::string
+BranchNonPCRel::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ std::string str;
+ if (symtab && symtab->findSymbol(targetAddr, str))
+ ss << str;
+ else
+ ccprintf(ss, "0x%x", targetAddr);
+
+ return ss.str();
+}
+
+Addr
+BranchPCRelCond::branchTarget(Addr pc) const
+{
+ return (uint32_t)(pc + disp);
+}
+
+std::string
+BranchPCRelCond::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ ss << bo << ", " << bi << ", ";
+
+ Addr target = pc + disp;
+
+ std::string str;
+ if (symtab && symtab->findSymbol(target, str))
+ ss << str;
+ else
+ ccprintf(ss, "0x%x", target);
+
+ return ss.str();
+}
+
+Addr
+BranchNonPCRelCond::branchTarget(Addr pc) const
+{
+ return targetAddr;
+}
+
+std::string
+BranchNonPCRelCond::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+{
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ ss << bo << ", " << bi << ", ";
+
+ std::string str;
+ if (symtab && symtab->findSymbol(targetAddr, str))
+ ss << str;
+ else
+ ccprintf(ss, "0x%x", targetAddr);
+
+ return ss.str();
+}
+
+Addr
+BranchRegCond::branchTarget(ThreadContext *tc) const
+{
+ uint32_t regVal = tc->readIntReg(_srcRegIdx[_numSrcRegs - 1]);
+ return (regVal & 0xfffffffc);
+}
+
+std::string
+BranchRegCond::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+{
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ ss << bo << ", " << bi << ", ";
+
+ return ss.str();
+}
diff --git a/src/arch/power/insts/branch.hh b/src/arch/power/insts/branch.hh
new file mode 100644
index 000000000..dd00e42c3
--- /dev/null
+++ b/src/arch/power/insts/branch.hh
@@ -0,0 +1,241 @@
+/* Copyright (c) 2007-2008 The Florida State University
+ * Copyright (c) 2009 The University of Edinburgh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Timothy M. Jones
+ */
+
+#ifndef __ARCH_POWER_INSTS_BRANCH_HH__
+#define __ARCH_POWER_INSTS_BRANCH_HH__
+
+#include "arch/power/insts/static_inst.hh"
+
+namespace PowerISA
+{
+
+/**
+ * Base class for instructions whose disassembly is not purely a
+ * function of the machine instruction (i.e., it depends on the
+ * PC). This class overrides the disassemble() method to check
+ * the PC and symbol table values before re-using a cached
+ * disassembly string. This is necessary for branches and jumps,
+ * where the disassembly string includes the target address (which
+ * may depend on the PC and/or symbol table).
+ */
+class PCDependentDisassembly : public PowerStaticInst
+{
+ protected:
+ /// Cached program counter from last disassembly
+ mutable Addr cachedPC;
+ /// Cached symbol table pointer from last disassembly
+ mutable const SymbolTable *cachedSymtab;
+
+ /// Constructor
+ PCDependentDisassembly(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass)
+ : PowerStaticInst(mnem, _machInst, __opClass),
+ cachedPC(0), cachedSymtab(0)
+ {
+ }
+
+ const std::string &
+ disassemble(Addr pc, const SymbolTable *symtab) const;
+};
+
+/**
+ * Base class for unconditional, PC-relative branches.
+ */
+class BranchPCRel : public PCDependentDisassembly
+{
+ protected:
+
+ /// Displacement
+ uint32_t disp;
+
+ /// Constructor.
+ BranchPCRel(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : PCDependentDisassembly(mnem, _machInst, __opClass),
+ disp(machInst.li << 2)
+ {
+ // If bit 26 is 1 then sign extend
+ if (disp & 0x2000000) {
+ disp |= 0xfc000000;
+ }
+ }
+
+ Addr branchTarget(Addr pc) const;
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+/**
+ * Base class for unconditional, non PC-relative branches.
+ */
+class BranchNonPCRel : public PCDependentDisassembly
+{
+ protected:
+
+ /// Target address
+ uint32_t targetAddr;
+
+ /// Constructor.
+ BranchNonPCRel(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : PCDependentDisassembly(mnem, _machInst, __opClass),
+ targetAddr(machInst.li << 2)
+ {
+ // If bit 26 is 1 then sign extend
+ if (targetAddr & 0x2000000) {
+ targetAddr |= 0xfc000000;
+ }
+ }
+
+ Addr branchTarget(Addr pc) const;
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+/**
+ * Base class for conditional branches.
+ */
+class BranchCond : public PCDependentDisassembly
+{
+ protected:
+
+ /// Fields needed for conditions
+ uint32_t bo;
+ uint32_t bi;
+
+ /// Constructor.
+ BranchCond(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : PCDependentDisassembly(mnem, _machInst, __opClass),
+ bo(machInst.bo),
+ bi(machInst.bi)
+ {
+ }
+
+ inline bool
+ ctrOk(uint32_t& ctr) const
+ {
+ bool ctr_ok;
+ if (bo & 4) {
+ ctr_ok = true;
+ } else {
+ ctr--;
+ if (ctr != 0) {
+ ctr_ok = ((bo & 2) == 0);
+ } else {
+ ctr_ok = ((bo & 2) != 0);
+ }
+ }
+ return ctr_ok;
+ }
+
+ inline bool
+ condOk(uint32_t cr) const
+ {
+ bool cond_ok;
+ if (bo & 16) {
+ cond_ok = true;
+ } else {
+ cond_ok = (((cr >> (31 - bi)) & 1) == ((bo >> 3) & 1));
+ }
+ return cond_ok;
+ }
+};
+
+/**
+ * Base class for conditional, PC-relative branches.
+ */
+class BranchPCRelCond : public BranchCond
+{
+ protected:
+
+ /// Displacement
+ uint32_t disp;
+
+ /// Constructor.
+ BranchPCRelCond(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : BranchCond(mnem, _machInst, __opClass),
+ disp(machInst.bd << 2)
+ {
+ // If bit 16 is 1 then sign extend
+ if (disp & 0x8000) {
+ disp |= 0xffff0000;
+ }
+ }
+
+ Addr branchTarget(Addr pc) const;
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+/**
+ * Base class for conditional, non PC-relative branches.
+ */
+class BranchNonPCRelCond : public BranchCond
+{
+ protected:
+
+ /// Target address
+ uint32_t targetAddr;
+
+ /// Constructor.
+ BranchNonPCRelCond(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : BranchCond(mnem, _machInst, __opClass),
+ targetAddr(machInst.bd << 2)
+ {
+ // If bit 16 is 1 then sign extend
+ if (targetAddr & 0x8000) {
+ targetAddr |= 0xffff0000;
+ }
+ }
+
+ Addr branchTarget(Addr pc) const;
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+/**
+ * Base class for conditional, register-based branches
+ */
+class BranchRegCond : public BranchCond
+{
+ protected:
+
+ /// Constructor.
+ BranchRegCond(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : BranchCond(mnem, _machInst, __opClass)
+ {
+ }
+
+ Addr branchTarget(ThreadContext *tc) const;
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+} // PowerISA namespace
+
+#endif //__ARCH_POWER_INSTS_BRANCH_HH__
diff --git a/src/mem/slicc/symbols/Var.cc b/src/arch/power/insts/condition.cc
index a6e8dfd55..0a942a982 100644
--- a/src/mem/slicc/symbols/Var.cc
+++ b/src/arch/power/insts/condition.cc
@@ -1,6 +1,5 @@
-
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009 The University of Edinburgh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,33 +24,36 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Timothy M. Jones
*/
-/*
- * $Id$
- *
- * */
+#include "arch/power/insts/condition.hh"
-#include "mem/slicc/symbols/Var.hh"
-#include "mem/slicc/symbols/StateMachine.hh"
+using namespace PowerISA;
-Var::Var(string id, const Location& location,
- Type* type_ptr, string code,
- const Map<string, string>& pairs,
- StateMachine* machine_ptr) : Symbol(id, location, pairs)
+std::string
+CondLogicOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
- if (machine_ptr == NULL) {
- m_c_id = id;
- } else {
- m_c_id = machine_ptr->toString() + "_" + id; // Append with machine name
- }
-
- m_machine_ptr = machine_ptr;
- m_type_ptr = type_ptr;
- m_code = code;
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ // Format is <mnemonic> bt, ba, bb
+ ss << bt << ", " << ba << ", " << bb;
+
+ return ss.str();
}
-void Var::print(ostream& out) const
+std::string
+CondMoveOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
- out << "[Var id: " << m_c_id << "]" << endl;
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ // Format is <mnemonic> bf, bfa
+ ss << bf << ", " << bfa;
+
+ return ss.str();
}
diff --git a/src/mem/slicc/ast/DeclAST.hh b/src/arch/power/insts/condition.hh
index d9e4555b4..a23667d9e 100644
--- a/src/mem/slicc/ast/DeclAST.hh
+++ b/src/arch/power/insts/condition.hh
@@ -1,6 +1,5 @@
-
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009 The University of Edinburgh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,61 +24,63 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * DeclAST.hh
- *
- * Description:
- *
- * $Id$
*
+ * Authors: Timothy M. Jones
*/
-#ifndef DECLAST_H
-#define DECLAST_H
+#ifndef __ARCH_POWER_INSTS_CONDITION_HH__
+#define __ARCH_POWER_INSTS_CONDITION_HH__
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/AST.hh"
-#include "mem/slicc/ast/PairListAST.hh"
-#include "mem/slicc/symbols/StateMachine.hh"
-#include "mem/slicc/ast/TypeAST.hh"
+#include "arch/power/insts/static_inst.hh"
+#include "base/cprintf.hh"
-class DeclAST : public AST {
-public:
- // Constructors
- DeclAST(PairListAST* pairs_ptr) : AST(pairs_ptr->getPairs()) {}
-
- // Destructor
- virtual ~DeclAST() {}
+namespace PowerISA
+{
- // Public Methods
- virtual void generate() = 0;
- virtual void findMachines() {};
+/**
+ * Class for condition register logical operations.
+ */
+class CondLogicOp : public PowerStaticInst
+{
+ protected:
- // void print(ostream& out) const;
-private:
- // Private Methods
+ uint32_t ba;
+ uint32_t bb;
+ uint32_t bt;
- // Private copy constructor and assignment operator
- // DeclAST(const DeclAST& obj);
- // DeclAST& operator=(const DeclAST& obj);
+ /// Constructor
+ CondLogicOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : PowerStaticInst(mnem, _machInst, __opClass),
+ ba(machInst.ba),
+ bb(machInst.bb),
+ bt(machInst.bt)
+ {
+ }
- // Data Members (m_ prefix)
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
-// Output operator declaration
-ostream& operator<<(ostream& out, const DeclAST& obj);
+/**
+ * Class for condition register move operations.
+ */
+class CondMoveOp : public PowerStaticInst
+{
+ protected:
+
+ uint32_t bf;
+ uint32_t bfa;
-// ******************* Definitions *******************
+ /// Constructor
+ CondMoveOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : PowerStaticInst(mnem, _machInst, __opClass),
+ bf(machInst.bf),
+ bfa(machInst.bfa)
+ {
+ }
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const DeclAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+} // PowerISA namespace
-#endif //DECLAST_H
+#endif //__ARCH_POWER_INSTS_CONDITION_HH__
diff --git a/src/arch/power/insts/floating.cc b/src/arch/power/insts/floating.cc
new file mode 100644
index 000000000..f5c34ee2a
--- /dev/null
+++ b/src/arch/power/insts/floating.cc
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2009 The University of Edinburgh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Timothy M. Jones
+ */
+
+#include "arch/power/insts/floating.hh"
+
+using namespace PowerISA;
+
+std::string
+FloatOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ // Print the first destination only
+ if (_numDestRegs > 0) {
+ printReg(ss, _destRegIdx[0]);
+ }
+
+ // Print the (possibly) two source registers
+ if (_numSrcRegs > 0) {
+ if (_numDestRegs > 0) {
+ ss << ", ";
+ }
+ printReg(ss, _srcRegIdx[0]);
+ if (_numSrcRegs > 1) {
+ ss << ", ";
+ printReg(ss, _srcRegIdx[1]);
+ }
+ }
+
+ return ss.str();
+}
diff --git a/src/arch/power/insts/floating.hh b/src/arch/power/insts/floating.hh
new file mode 100644
index 000000000..2b2668409
--- /dev/null
+++ b/src/arch/power/insts/floating.hh
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2009 The University of Edinburgh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Timothy M. Jones
+ * Korey Sewell
+ */
+
+#ifndef __ARCH_POWER_INSTS_FLOATING_HH__
+#define __ARCH_POWER_INSTS_FLOATING_HH__
+
+#include "arch/power/insts/static_inst.hh"
+#include "base/cprintf.hh"
+#include "base/bitfield.hh"
+
+namespace PowerISA
+{
+
+/**
+ * Base class for floating point operations.
+ */
+class FloatOp : public PowerStaticInst
+{
+ protected:
+
+ bool rcSet;
+
+ /// Constructor
+ FloatOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : PowerStaticInst(mnem, _machInst, __opClass)
+ {
+ }
+
+ // Test for NaN (maximum biased exponent & non-zero fraction)
+ inline bool
+ isNan(uint32_t val_bits) const
+ {
+ return ((bits(val_bits, 30, 23) == 0xFF) && bits(val_bits, 22, 0));
+ }
+
+ inline bool
+ isNan(uint64_t val_bits) const
+ {
+ return ((bits(val_bits, 62, 52) == 0x7FF) && bits(val_bits, 51, 0));
+ }
+
+ inline bool
+ isNan(float val) const
+ {
+ void *val_ptr = &val;
+ uint32_t val_bits = *(uint32_t *) val_ptr;
+ return isNan(val_bits);
+ }
+
+ inline bool
+ isNan(double val) const
+ {
+ void *val_ptr = &val;
+ uint64_t val_bits = *(uint64_t *) val_ptr;
+ return isNan(val_bits);
+ }
+
+ // Test for SNaN (NaN with high order bit of fraction set to 0)
+ inline bool
+ isSnan(uint32_t val_bits) const
+ {
+ return ((bits(val_bits, 30, 22) == 0x1FE) && bits(val_bits, 22, 0));
+ }
+
+ // Test for QNaN (NaN with high order bit of fraction set to 1)
+ inline bool
+ isQnan(uint32_t val_bits) const
+ {
+ return (bits(val_bits, 30, 22) == 0x1FF);
+ }
+
+ // Test for infinity (maximum biased exponent and zero fraction)
+ inline bool
+ isInfinity(uint32_t val_bits) const
+ {
+ return ((bits(val_bits, 30, 23) == 0xFF) && !bits(val_bits, 22, 0));
+ }
+
+ // Test for normalized numbers (biased exponent in the range 1 to 254)
+ inline bool
+ isNormalized(uint32_t val_bits) const
+ {
+ return ((bits(val_bits, 30, 23) != 0xFF) && bits(val_bits, 22, 0));
+ }
+
+ // Test for denormalized numbers (biased exponent of zero and
+ // non-zero fraction)
+ inline bool
+ isDenormalized(uint32_t val_bits) const
+ {
+ return (!bits(val_bits, 30, 23) && bits(val_bits, 22, 0));
+ }
+
+ // Test for zero (biased exponent of zero and fraction of zero)
+ inline bool
+ isZero(uint32_t val_bits) const
+ {
+ return (!bits(val_bits, 30, 23) && !bits(val_bits, 22, 0));
+ }
+
+ // Test for negative
+ inline bool
+ isNegative(uint32_t val_bits) const
+ {
+ return (bits(val_bits, 31));
+ }
+
+ // Compute the CR field
+ inline uint32_t
+ makeCRField(double a, double b) const
+ {
+ uint32_t c = 0;
+ if (isNan(a) || isNan(b)) { c = 0x1; }
+ else if (a < b) { c = 0x8; }
+ else if (a > b) { c = 0x4; }
+ else { c = 0x2; }
+ return c;
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+} // PowerISA namespace
+
+#endif //__ARCH_POWER_INSTS_FLOATING_HH__
diff --git a/src/arch/power/insts/integer.cc b/src/arch/power/insts/integer.cc
new file mode 100644
index 000000000..1f81a15dc
--- /dev/null
+++ b/src/arch/power/insts/integer.cc
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2009 The University of Edinburgh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Timothy M. Jones
+ */
+
+#include "arch/power/insts/integer.hh"
+
+using namespace std;
+using namespace PowerISA;
+
+string
+IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+ stringstream ss;
+ bool printDest = true;
+ bool printSrcs = true;
+ bool printSecondSrc = true;
+
+ // Generate the correct mnemonic
+ string myMnemonic(mnemonic);
+
+ // Special cases
+ if (!myMnemonic.compare("or") && _srcRegIdx[0] == _srcRegIdx[1]) {
+ myMnemonic = "mr";
+ printSecondSrc = false;
+ } else if (!myMnemonic.compare("mtlr") || !myMnemonic.compare("cmpi")) {
+ printDest = false;
+ } else if (!myMnemonic.compare("mflr")) {
+ printSrcs = false;
+ }
+
+ // Additional characters depending on isa bits being set
+ if (oeSet) myMnemonic = myMnemonic + "o";
+ if (rcSet) myMnemonic = myMnemonic + ".";
+ ccprintf(ss, "%-10s ", myMnemonic);
+
+ // Print the first destination only
+ if (_numDestRegs > 0 && printDest) {
+ printReg(ss, _destRegIdx[0]);
+ }
+
+ // Print the (possibly) two source registers
+ if (_numSrcRegs > 0 && printSrcs) {
+ if (_numDestRegs > 0 && printDest) {
+ ss << ", ";
+ }
+ printReg(ss, _srcRegIdx[0]);
+ if (_numSrcRegs > 1 && printSecondSrc) {
+ ss << ", ";
+ printReg(ss, _srcRegIdx[1]);
+ }
+ }
+
+ return ss.str();
+}
+
+
+string
+IntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+ stringstream ss;
+
+ // Generate the correct mnemonic
+ string myMnemonic(mnemonic);
+
+ // Special cases
+ if (!myMnemonic.compare("addi") && _numSrcRegs == 0) {
+ myMnemonic = "li";
+ } else if (!myMnemonic.compare("addis") && _numSrcRegs == 0) {
+ myMnemonic = "lis";
+ }
+ ccprintf(ss, "%-10s ", myMnemonic);
+
+ // Print the first destination only
+ if (_numDestRegs > 0) {
+ printReg(ss, _destRegIdx[0]);
+ }
+
+ // Print the source register
+ if (_numSrcRegs > 0) {
+ if (_numDestRegs > 0) {
+ ss << ", ";
+ }
+ printReg(ss, _srcRegIdx[0]);
+ }
+
+ // Print the immediate value last
+ ss << ", " << (int32_t)imm;
+
+ return ss.str();
+}
+
+
+string
+IntShiftOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+ stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ // Print the first destination only
+ if (_numDestRegs > 0) {
+ printReg(ss, _destRegIdx[0]);
+ }
+
+ // Print the first source register
+ if (_numSrcRegs > 0) {
+ if (_numDestRegs > 0) {
+ ss << ", ";
+ }
+ printReg(ss, _srcRegIdx[0]);
+ }
+
+ // Print the shift
+ ss << ", " << sh;
+
+ return ss.str();
+}
+
+
+string
+IntRotateOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+ stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ // Print the first destination only
+ if (_numDestRegs > 0) {
+ printReg(ss, _destRegIdx[0]);
+ }
+
+ // Print the first source register
+ if (_numSrcRegs > 0) {
+ if (_numDestRegs > 0) {
+ ss << ", ";
+ }
+ printReg(ss, _srcRegIdx[0]);
+ }
+
+ // Print the shift, mask begin and mask end
+ ss << ", " << sh << ", " << mb << ", " << me;
+
+ return ss.str();
+}
diff --git a/src/arch/power/insts/integer.hh b/src/arch/power/insts/integer.hh
new file mode 100644
index 000000000..b4b96d5dc
--- /dev/null
+++ b/src/arch/power/insts/integer.hh
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2009 The University of Edinburgh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Timothy M. Jones
+ */
+
+#ifndef __ARCH_POWER_INSTS_INTEGER_HH__
+#define __ARCH_POWER_INSTS_INTEGER_HH__
+
+#include "arch/power/insts/static_inst.hh"
+#include "base/cprintf.hh"
+#include "base/bitfield.hh"
+
+namespace PowerISA
+{
+
+/**
+ * We provide a base class for integer operations and then inherit for
+ * several other classes. These specialise for instructions using immediate
+ * values and also rotate instructions. We also need to have versions that
+ * consider the Rc and OE bits.
+ */
+
+/**
+ * Base class for integer operations.
+ */
+class IntOp : public PowerStaticInst
+{
+ protected:
+
+ bool rcSet;
+ bool oeSet;
+
+ // Needed for srawi only
+ uint32_t sh;
+
+ /// Constructor
+ IntOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : PowerStaticInst(mnem, _machInst, __opClass),
+ rcSet(false), oeSet(false)
+ {
+ }
+
+ /* Compute the CR (condition register) field using signed comparison */
+ inline uint32_t
+ makeCRField(int32_t a, int32_t b, uint32_t xerSO) const
+ {
+ uint32_t c = xerSO;
+
+ /* We've pre-shifted the immediate values here */
+ if (a < b) { c += 0x8; }
+ else if (a > b) { c += 0x4; }
+ else { c += 0x2; }
+ return c;
+ }
+
+ /* Compute the CR (condition register) field using unsigned comparison */
+ inline uint32_t
+ makeCRField(uint32_t a, uint32_t b, uint32_t xerSO) const
+ {
+ uint32_t c = xerSO;
+
+ /* We've pre-shifted the immediate values here */
+ if (a < b) { c += 0x8; }
+ else if (a > b) { c += 0x4; }
+ else { c += 0x2; }
+ return c;
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+
+/**
+ * Class for integer immediate (signed and unsigned) operations.
+ */
+class IntImmOp : public IntOp
+{
+ protected:
+
+ int32_t imm;
+ uint32_t uimm;
+
+ /// Constructor
+ IntImmOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : IntOp(mnem, _machInst, __opClass),
+ imm(sext<16>(machInst.si)),
+ uimm(machInst.si)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+
+/**
+ * Class for integer operations with a shift.
+ */
+class IntShiftOp : public IntOp
+{
+ protected:
+
+ uint32_t sh;
+
+ /// Constructor
+ IntShiftOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : IntOp(mnem, _machInst, __opClass),
+ sh(machInst.sh)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+
+/**
+ * Class for integer rotate operations.
+ */
+class IntRotateOp : public IntShiftOp
+{
+ protected:
+
+ uint32_t mb;
+ uint32_t me;
+ uint32_t fullMask;
+
+ /// Constructor
+ IntRotateOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : IntShiftOp(mnem, _machInst, __opClass),
+ mb(machInst.mb),
+ me(machInst.me)
+ {
+ if (me >= mb) {
+ fullMask = mask(31 - mb, 31 - me);
+ } else {
+ fullMask = ~mask(31 - (me + 1), 31 - (mb - 1));
+ }
+ }
+
+ uint32_t
+ rotateValue(uint32_t rs, uint32_t shift) const
+ {
+ uint32_t n = shift & 31;
+ return (rs << n) | (rs >> (32 - n));
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+} // PowerISA namespace
+
+#endif //__ARCH_POWER_INSTS_INTEGER_HH__
diff --git a/src/mem/slicc/ast/DeclListAST.cc b/src/arch/power/insts/mem.cc
index 8337d714b..447efa2f4 100644
--- a/src/mem/slicc/ast/DeclListAST.cc
+++ b/src/arch/power/insts/mem.cc
@@ -1,6 +1,5 @@
-
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009 The University of Edinburgh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,62 +24,51 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * DeclListAST.C
- *
- * Description: See DeclListAST.hh
- *
- * $Id$
*
+ * Authors: Timothy M. Jones
*/
-#include "mem/slicc/ast/DeclListAST.hh"
+#include "arch/power/insts/mem.hh"
+#include "base/loader/symtab.hh"
-DeclListAST::DeclListAST(Vector<DeclAST*>* vec_ptr)
- : AST()
-{
- assert(vec_ptr != NULL);
- m_vec_ptr = vec_ptr;
-}
+using namespace PowerISA;
-// Singleton constructor.
-DeclListAST::DeclListAST(DeclAST* Decl_ptr)
- : AST()
+std::string
+MemOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
- assert(Decl_ptr != NULL);
- m_vec_ptr = new Vector<DeclAST*>;
- m_vec_ptr->insertAtTop(Decl_ptr);
+ return csprintf("%-10s", mnemonic);
}
-DeclListAST::~DeclListAST()
+std::string
+MemDispOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
- int size = m_vec_ptr->size();
- for(int i=0; i<size; i++) {
- delete (*m_vec_ptr)[i];
- }
- delete m_vec_ptr;
-}
+ std::stringstream ss;
-void DeclListAST::generate() const
-{
- int size = m_vec_ptr->size();
- for(int i=0; i<size; i++) {
- (*m_vec_ptr)[i]->generate();
- }
-}
+ ccprintf(ss, "%-10s ", mnemonic);
-void DeclListAST::findMachines() const
-{
- int size = m_vec_ptr->size();
- for(int i=0; i<size; i++) {
- (*m_vec_ptr)[i]->findMachines();
- }
-}
+ // Print the destination only for a load
+ if (!flags[IsStore]) {
+ if (_numDestRegs > 0) {
-void DeclListAST::print(ostream& out) const
-{
- assert(m_vec_ptr != NULL);
- out << "[DeclListAST: " << *m_vec_ptr << "]";
+ // If the instruction updates the source register with the
+ // EA, then this source register is placed in position 0,
+ // therefore we print the last destination register.
+ printReg(ss, _destRegIdx[_numDestRegs-1]);
+ }
+ }
+
+ // Print the data register for a store
+ else {
+ printReg(ss, _srcRegIdx[1]);
+ }
+
+ // Print the displacement
+ ss << ", " << (int32_t)disp;
+
+ // Print the address register
+ ss << "(";
+ printReg(ss, _srcRegIdx[0]);
+ ss << ")";
+
+ return ss.str();
}
diff --git a/src/mem/slicc/ast/TypeDeclAST.cc b/src/arch/power/insts/mem.hh
index bbf2f8491..329dafe57 100644
--- a/src/mem/slicc/ast/TypeDeclAST.cc
+++ b/src/arch/power/insts/mem.hh
@@ -1,6 +1,5 @@
-
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009 The University of Edinburgh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,62 +24,68 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * TypeDeclAST.C
- *
- * Description: See TypeDeclAST.hh
- *
- * $Id: TypeDeclAST.C,v 3.1 2003/03/22 15:15:17 xu Exp $
*
+ * Authors: Timothy M. Jones
*/
-#include "mem/slicc/ast/TypeDeclAST.hh"
-#include "mem/slicc/main.hh"
-#include "mem/slicc/symbols/SymbolTable.hh"
+#ifndef __ARCH_POWER_MEM_HH__
+#define __ARCH_POWER_MEM_HH__
-TypeDeclAST::TypeDeclAST(TypeAST* type_ast_ptr,
- PairListAST* pairs_ptr,
- Vector<TypeFieldAST*>* field_vec_ptr)
- : DeclAST(pairs_ptr)
+#include "arch/power/insts/static_inst.hh"
+
+namespace PowerISA
{
- m_type_ast_ptr = type_ast_ptr;
- m_field_vec_ptr = field_vec_ptr;
-}
-TypeDeclAST::~TypeDeclAST()
+/**
+ * Base class for memory operations.
+ */
+class MemOp : public PowerStaticInst
{
- delete m_type_ast_ptr;
- if (m_field_vec_ptr != NULL) {
- int size = m_field_vec_ptr->size();
- for(int i=0; i<size; i++) {
- delete (*m_field_vec_ptr)[i];
+ protected:
+
+ /// Memory request flags. See mem_req_base.hh.
+ unsigned memAccessFlags;
+ /// Pointer to EAComp object.
+ const StaticInstPtr eaCompPtr;
+ /// Pointer to MemAcc object.
+ const StaticInstPtr memAccPtr;
+
+ /// Constructor
+ MemOp(const char *mnem, MachInst _machInst, OpClass __opClass,
+ StaticInstPtr _eaCompPtr = nullStaticInstPtr,
+ StaticInstPtr _memAccPtr = nullStaticInstPtr)
+ : PowerStaticInst(mnem, _machInst, __opClass),
+ memAccessFlags(0),
+ eaCompPtr(_eaCompPtr),
+ memAccPtr(_memAccPtr)
+ {
}
- delete m_field_vec_ptr;
- }
-}
-void TypeDeclAST::generate()
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+
+/**
+ * Class for memory operations with displacement.
+ */
+class MemDispOp : public MemOp
{
- string machine_name;
- string id = m_type_ast_ptr->toString();
+ protected:
- // Make the new type
- Type* new_type_ptr = new Type(id, getLocation(), getPairs(),
- g_sym_table.getStateMachine());
- g_sym_table.newSym(new_type_ptr);
+ int16_t disp;
- // Add all of the fields of the type to it
- if (m_field_vec_ptr != NULL) {
- int size = m_field_vec_ptr->size();
- for(int i=0; i<size; i++) {
- (*m_field_vec_ptr)[i]->generate(new_type_ptr);
+ /// Constructor
+ MemDispOp(const char *mnem, MachInst _machInst, OpClass __opClass,
+ StaticInstPtr _eaCompPtr = nullStaticInstPtr,
+ StaticInstPtr _memAccPtr = nullStaticInstPtr)
+ : MemOp(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
+ disp(machInst.d)
+ {
}
- }
-}
-void TypeDeclAST::print(ostream& out) const
-{
- out << "[TypeDecl: " << m_type_ast_ptr->toString() << "]";
-}
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+} // PowerISA namespace
+
+#endif //__ARCH_POWER_INSTS_MEM_HH__
diff --git a/src/arch/power/insts/misc.cc b/src/arch/power/insts/misc.cc
new file mode 100644
index 000000000..913030b61
--- /dev/null
+++ b/src/arch/power/insts/misc.cc
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2009 The University of Edinburgh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Timothy M. Jones
+ */
+
+#include "arch/power/insts/misc.hh"
+
+using namespace PowerISA;
+
+std::string
+MiscOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ // Print the first destination only
+ if (_numDestRegs > 0) {
+ printReg(ss, _destRegIdx[0]);
+ }
+
+ // Print the (possibly) two source registers
+ if (_numSrcRegs > 0) {
+ if (_numDestRegs > 0) {
+ ss << ", ";
+ }
+ printReg(ss, _srcRegIdx[0]);
+ if (_numSrcRegs > 1) {
+ ss << ", ";
+ printReg(ss, _srcRegIdx[1]);
+ }
+ }
+
+ return ss.str();
+}
diff --git a/src/mem/slicc/ast/LiteralExprAST.cc b/src/arch/power/insts/misc.hh
index 4e384a3b3..dd4941b93 100644
--- a/src/mem/slicc/ast/LiteralExprAST.cc
+++ b/src/arch/power/insts/misc.hh
@@ -1,6 +1,5 @@
-
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009 The University of Edinburgh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,31 +24,34 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * LiteralExprAST.C
- *
- * Description: See LiteralExprAST.hh
- *
- * $Id: LiteralExprAST.C,v 3.1 2002/10/22 21:27:52 milo Exp $
*
+ * Authors: Timothy M. Jones
*/
-#include "mem/slicc/ast/LiteralExprAST.hh"
+#ifndef __ARCH_POWER_INSTS_MISC_HH__
+#define __ARCH_POWER_INSTS_MISC_HH__
+
+#include "arch/power/insts/static_inst.hh"
-Type* LiteralExprAST::generate(string& code) const
+namespace PowerISA
{
- if (m_type == "string") {
- code += "(\"" + *m_lit_ptr + "\")";
- } else {
- code += "(" + *m_lit_ptr + ")";
- }
-
- Type* type_ptr = g_sym_table.getType(m_type);
- if (type_ptr == NULL) {
- // Can't find the type
- error("Internal: can't primitive type '" + m_type + "'");
- }
- return type_ptr;
-}
+
+/**
+ * Class for misc operations.
+ */
+class MiscOp : public PowerStaticInst
+{
+ protected:
+
+ /// Constructor
+ MiscOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : PowerStaticInst(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+} // PowerISA namespace
+
+#endif //__ARCH_POWER_INSTS_MISC_HH__
diff --git a/src/arch/power/insts/static_inst.cc b/src/arch/power/insts/static_inst.cc
new file mode 100644
index 000000000..1982744bf
--- /dev/null
+++ b/src/arch/power/insts/static_inst.cc
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2009 The University of Edinburgh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Timothy M. Jones
+ */
+
+#include "arch/power/insts/static_inst.hh"
+
+using namespace PowerISA;
+
+void
+PowerStaticInst::printReg(std::ostream &os, int reg) const
+{
+ if (reg < FP_Base_DepTag) {
+ ccprintf(os, "r%d", reg);
+ } else if (reg < Ctrl_Base_DepTag) {
+ ccprintf(os, "f%d", reg - FP_Base_DepTag);
+ } else {
+ switch (reg - Ctrl_Base_DepTag) {
+ case 0: ccprintf(os, "cr"); break;
+ case 1: ccprintf(os, "xer"); break;
+ case 2: ccprintf(os, "lr"); break;
+ case 3: ccprintf(os, "ctr"); break;
+ default: ccprintf(os, "unknown_reg");
+ }
+ }
+}
+
+std::string
+PowerStaticInst::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+{
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ return ss.str();
+}
diff --git a/src/mem/slicc/ast/PairListAST.hh b/src/arch/power/insts/static_inst.hh
index 7edcdc1e7..399e75371 100644
--- a/src/mem/slicc/ast/PairListAST.hh
+++ b/src/arch/power/insts/static_inst.hh
@@ -1,6 +1,5 @@
-
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009 The University of Edinburgh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,58 +24,47 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * PairListAST.hh
- *
- * Description:
- *
- * $Id$
*
+ * Authors: Timothy M. Jones
*/
-#ifndef PairListAST_H
-#define PairListAST_H
+#ifndef __ARCH_POWER_INSTS_STATICINST_HH__
+#define __ARCH_POWER_INSTS_STATICINST_HH__
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/AST.hh"
-#include "mem/slicc/ast/PairAST.hh"
+#include "base/trace.hh"
+#include "cpu/static_inst.hh"
+namespace PowerISA
+{
-class PairListAST : public AST {
-public:
- // Constructors
- PairListAST() : AST() {}
+class PowerStaticInst : public StaticInst
+{
+ protected:
- // Destructor
- //~PairListAST();
+ // Constructor
+ PowerStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : StaticInst(mnem, _machInst, __opClass)
+ {
+ }
- // Public Methods
- void addPair(PairAST* pair_ptr);
- void print(ostream& out) const;
-private:
- // Private Methods
+ // Insert a condition value into a CR (condition register) field
+ inline uint32_t
+ insertCRField(uint32_t cr, uint32_t bf, uint32_t value) const
+ {
+ uint32_t bits = value << ((7 - bf) * 4);
+ uint32_t mask = ~(0xf << ((7 - bf) * 4));
+ return (cr & mask) | bits;
+ }
- // Private copy constructor and assignment operator
- PairListAST(const PairListAST& obj);
- PairListAST& operator=(const PairListAST& obj);
+ /// Print a register name for disassembly given the unique
+ /// dependence tag number (FP or int).
+ void
+ printReg(std::ostream &os, int reg) const;
- // Data Members (m_ prefix)
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
-// Output operator declaration
-ostream& operator<<(ostream& out, const PairListAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const PairListAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
+} // PowerISA namespace
-#endif //PairListAST_H
+#endif //__ARCH_POWER_INSTS_STATICINST_HH__
diff --git a/src/arch/power/isa.hh b/src/arch/power/isa.hh
new file mode 100644
index 000000000..ba1b5018d
--- /dev/null
+++ b/src/arch/power/isa.hh
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2009 The Regents of The University of Michigan
+ * Copyright (c) 2009 The University of Edinburgh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ * Timothy M. Jones
+ */
+
+#ifndef __ARCH_POWER_ISA_HH__
+#define __ARCH_POWER_ISA_HH__
+
+#include "arch/power/registers.hh"
+#include "arch/power/types.hh"
+#include "base/misc.hh"
+
+class ThreadContext;
+class Checkpoint;
+class EventManager;
+
+namespace PowerISA
+{
+
+class ISA
+{
+ protected:
+ MiscReg dummy;
+ MiscReg miscRegs[NumMiscRegs];
+
+ public:
+ void
+ clear()
+ {
+ }
+
+ MiscReg
+ readMiscRegNoEffect(int misc_reg)
+ {
+ fatal("Power does not currently have any misc regs defined\n");
+ return dummy;
+ }
+
+ MiscReg
+ readMiscReg(int misc_reg, ThreadContext *tc)
+ {
+ fatal("Power does not currently have any misc regs defined\n");
+ return dummy;
+ }
+
+ void
+ setMiscRegNoEffect(int misc_reg, const MiscReg &val)
+ {
+ fatal("Power does not currently have any misc regs defined\n");
+ }
+
+ void
+ setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
+ {
+ fatal("Power does not currently have any misc regs defined\n");
+ }
+
+ int
+ flattenIntIndex(int reg)
+ {
+ return reg;
+ }
+
+ int
+ flattenFloatIndex(int reg)
+ {
+ return reg;
+ }
+
+ void
+ serialize(EventManager *em, std::ostream &os)
+ {
+ }
+
+ void
+ unserialize(EventManager *em, Checkpoint *cp, const std::string &section)
+ {
+ }
+
+ ISA()
+ {
+ clear();
+ }
+};
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_ISA_HH__
diff --git a/src/arch/power/isa/bitfields.isa b/src/arch/power/isa/bitfields.isa
new file mode 100644
index 000000000..8cd323ad5
--- /dev/null
+++ b/src/arch/power/isa/bitfields.isa
@@ -0,0 +1,84 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2009 The University of Edinburgh
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Timothy M. Jones
+
+////////////////////////////////////////////////////////////////////
+//
+// Bitfield definitions.
+//
+// The endianness is the opposite to what's used here, so things
+// are reversed sometimes. Not sure of a fix to this though...
+
+// Opcode fields
+def bitfield OPCODE <31:26>;
+def bitfield X_XO <10:0>;
+def bitfield XO_XO <10:1>;
+def bitfield A_XO <5:1>;
+
+// Register fields
+def bitfield RA <20:16>;
+def bitfield RB <15:11>;
+def bitfield RS <25:21>;
+def bitfield RT <25:21>;
+def bitfield FRA <20:16>;
+def bitfield FRB <15:11>;
+def bitfield FRC <10:6>;
+def bitfield FRS <25:21>;
+def bitfield FRT <25:21>;
+
+// The record bit can be in two positions
+// Used to enable setting of the condition register
+def bitfield RC31 <0>;
+def bitfield RC21 <10>;
+
+// Used to enable setting of the overflow flags
+def bitfield OE <10>;
+
+// SPR field for mtspr instruction
+def bitfield SPR <20:11>;
+
+// FXM field for mtcrf instruction
+def bitfield FXM <19:12>;
+
+// Branch fields
+def bitfield LK <0>;
+def bitfield AA <1>;
+
+// Specifies a CR or FPSCR field
+def bitfield BF <25:23>;
+
+// Fields for FPSCR manipulation instructions
+def bitfield FLM <24:17>;
+def bitfield L <25>;
+def bitfield W <16>;
+// Named so to avoid conflicts with range.hh
+def bitfield U_FIELD <15:12>;
+
+// Field for specifying a bit in CR or FPSCR
+def bitfield BT <25:21>;
diff --git a/src/arch/power/isa/decoder.isa b/src/arch/power/isa/decoder.isa
new file mode 100644
index 000000000..3252ff14a
--- /dev/null
+++ b/src/arch/power/isa/decoder.isa
@@ -0,0 +1,593 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2009 The University of Edinburgh
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Timothy M. Jones
+
+////////////////////////////////////////////////////////////////////
+//
+// The actual Power ISA decoder
+// ------------------------------
+//
+// I've used the Power ISA Book I v2.06 for instruction formats,
+// opcode numbers, register names, etc.
+//
+decode OPCODE default Unknown::unknown() {
+
+ format IntImmOp {
+ 10: cmpli({{
+ Xer xer = XER;
+ uint32_t cr = makeCRField(Ra, (uint32_t)uimm, xer.so);
+ CR = insertCRField(CR, BF, cr);
+ }});
+ 11: cmpi({{
+ Xer xer = XER;
+ uint32_t cr = makeCRField(Ra.sw, (int32_t)imm, xer.so);
+ CR = insertCRField(CR, BF, cr);
+ }});
+ }
+
+ // Some instructions use bits 21 - 30, others 22 - 30. We have to use
+ // the larger size to account for all opcodes. For those that use the
+ // smaller value, the OE bit is bit 21. Therefore, we have two versions
+ // of each instruction: 1 with OE set, the other without. For an
+ // example see 'add' and 'addo'.
+ 31: decode XO_XO {
+
+ // These instructions can all be reduced to the form
+ // Rt = src1 + src2 [+ CA], therefore we just give src1 and src2
+ // (and, if necessary, CA) definitions and let the python script
+ // deal with setting things up correctly. We also give flags to
+ // say which control registers to set.
+ format IntSumOp {
+ 266: add({{ Ra }}, {{ Rb }});
+ 40: subf({{ ~Ra }}, {{ Rb }}, {{ 1 }});
+ 10: addc({{ Ra }}, {{ Rb }},
+ computeCA = true);
+ 8: subfc({{ ~Ra }}, {{ Rb }}, {{ 1 }},
+ true);
+ 104: neg({{ ~Ra }}, {{ 1 }});
+ 138: adde({{ Ra }}, {{ Rb }}, {{ xer.ca }},
+ true);
+ 234: addme({{ Ra }}, {{ (uint32_t)-1 }}, {{ xer.ca }},
+ true);
+ 136: subfe({{ ~Ra }}, {{ Rb }}, {{ xer.ca }},
+ true);
+ 232: subfme({{ ~Ra }}, {{ (uint32_t)-1 }}, {{ xer.ca }},
+ true);
+ 202: addze({{ Ra }}, {{ xer.ca }},
+ computeCA = true);
+ 200: subfze({{ ~Ra }}, {{ xer.ca }},
+ computeCA = true);
+ }
+
+ // Arithmetic instructions all use source registers Ra and Rb,
+ // with destination register Rt.
+ format IntArithOp {
+ 75: mulhw({{ int64_t prod = Ra.sq * Rb.sq; Rt = prod >> 32; }});
+ 11: mulhwu({{ uint64_t prod = Ra.uq * Rb.uq; Rt = prod >> 32; }});
+ 235: mullw({{ int64_t prod = Ra.sq * Rb.sq; Rt = prod; }});
+ 747: mullwo({{ int64_t src1 = Ra.sq; int64_t src2 = Rb; int64_t prod = src1 * src2; Rt = prod; }},
+ true);
+
+ 491: divw({{
+ int32_t src1 = Ra.sw;
+ int32_t src2 = Rb.sw;
+ if ((src1 != 0x80000000 || src2 != 0xffffffff)
+ && src2 != 0) {
+ Rt = src1 / src2;
+ } else {
+ Rt = 0;
+ }
+ }});
+
+ 1003: divwo({{
+ int32_t src1 = Ra.sw;
+ int32_t src2 = Rb.sw;
+ if ((src1 != 0x80000000 || src2 != 0xffffffff)
+ && src2 != 0) {
+ Rt = src1 / src2;
+ } else {
+ Rt = 0;
+ divSetOV = true;
+ }
+ }},
+ true);
+
+ 459: divwu({{
+ uint32_t src1 = Ra.sw;
+ uint32_t src2 = Rb.sw;
+ if (src2 != 0) {
+ Rt = src1 / src2;
+ } else {
+ Rt = 0;
+ }
+ }});
+
+ 971: divwuo({{
+ uint32_t src1 = Ra.sw;
+ uint32_t src2 = Rb.sw;
+ if (src2 != 0) {
+ Rt = src1 / src2;
+ } else {
+ Rt = 0;
+ divSetOV = true;
+ }
+ }},
+ true);
+ }
+
+ // Integer logic instructions use source registers Rs and Rb,
+ // with destination register Ra.
+ format IntLogicOp {
+ 28: and({{ Ra = Rs & Rb; }});
+ 316: xor({{ Ra = Rs ^ Rb; }});
+ 476: nand({{ Ra = ~(Rs & Rb); }});
+ 444: or({{ Ra = Rs | Rb; }});
+ 124: nor({{ Ra = ~(Rs | Rb); }});
+ 60: andc({{ Ra = Rs & ~Rb; }});
+ 954: extsb({{ Ra = sext<8>(Rs); }});
+ 284: eqv({{ Ra = ~(Rs ^ Rb); }});
+ 412: orc({{ Ra = Rs | ~Rb; }});
+ 922: extsh({{ Ra = sext<16>(Rs); }});
+ 26: cntlzw({{ Ra = Rs == 0 ? 32 : 31 - findMsbSet(Rs); }});
+ 508: cmpb({{
+ uint32_t val = 0;
+ for (int n = 0; n < 32; n += 8) {
+ if(bits(Rs, n, n+7) == bits(Rb, n, n+7)) {
+ val = insertBits(val, n, n+7, 0xff);
+ }
+ }
+ Ra = val;
+ }});
+
+ 24: slw({{
+ if (Rb & 0x20) {
+ Ra = 0;
+ } else {
+ Ra = Rs << (Rb & 0x1f);
+ }
+ }});
+
+ 536: srw({{
+ if (Rb & 0x20) {
+ Ra = 0;
+ } else {
+ Ra = Rs >> (Rb & 0x1f);
+ }
+ }});
+
+ 792: sraw({{
+ bool shiftSetCA = false;
+ int32_t s = Rs;
+ if (Rb == 0) {
+ Ra = Rs;
+ shiftSetCA = true;
+ } else if (Rb & 0x20) {
+ if (s < 0) {
+ Ra = (uint32_t)-1;
+ if (s & 0x7fffffff) {
+ shiftSetCA = true;
+ } else {
+ shiftSetCA = false;
+ }
+ } else {
+ Ra = 0;
+ shiftSetCA = false;
+ }
+ } else {
+ Ra = s >> (Rb & 0x1f);
+ if (s < 0 && (s << (32 - (Rb & 0x1f))) != 0) {
+ shiftSetCA = true;
+ } else {
+ shiftSetCA = false;
+ }
+ }
+ Xer xer1 = XER;
+ if (shiftSetCA) {
+ xer1.ca = 1;
+ } else {
+ xer1.ca = 0;
+ }
+ XER = xer1;
+ }});
+ }
+
+ // Integer logic instructions with a shift value.
+ format IntShiftOp {
+ 824: srawi({{
+ bool shiftSetCA = false;
+ if (sh == 0) {
+ Ra = Rs;
+ shiftSetCA = false;
+ } else {
+ int32_t s = Rs;
+ Ra = s >> sh;
+ if (s < 0 && (s << (32 - sh)) != 0) {
+ shiftSetCA = true;
+ } else {
+ shiftSetCA = false;
+ }
+ }
+ Xer xer1 = XER;
+ if (shiftSetCA) {
+ xer1.ca = 1;
+ } else {
+ xer1.ca = 0;
+ }
+ XER = xer1;
+ }});
+ }
+
+ // Generic integer format instructions.
+ format IntOp {
+ 0: cmp({{
+ Xer xer = XER;
+ uint32_t cr = makeCRField(Ra.sw, Rb.sw, xer.so);
+ CR = insertCRField(CR, BF, cr);
+ }});
+ 32: cmpl({{
+ Xer xer = XER;
+ uint32_t cr = makeCRField(Ra, Rb, xer.so);
+ CR = insertCRField(CR, BF, cr);
+ }});
+ 144: mtcrf({{
+ uint32_t mask = 0;
+ for (int i = 0; i < 8; ++i) {
+ if (((FXM >> i) & 0x1) == 0x1) {
+ mask |= 0xf << (4 * i);
+ }
+ }
+ CR = (Rs & mask) | (CR & ~mask);
+ }});
+ 19: mfcr({{ Rt = CR; }});
+ 339: decode SPR {
+ 0x20: mfxer({{ Rt = XER; }});
+ 0x100: mflr({{ Rt = LR; }});
+ 0x120: mfctr({{ Rt = CTR; }});
+ }
+ 467: decode SPR {
+ 0x20: mtxer({{ XER = Rs; }});
+ 0x100: mtlr({{ LR = Rs; }});
+ 0x120: mtctr({{ CTR = Rs; }});
+ }
+ }
+
+ // All loads with an index register. The non-update versions
+ // all use the value 0 if Ra == R0, not the value contained in
+ // R0. Others update Ra with the effective address. In all cases,
+ // Ra and Rb are source registers, Rt is the destintation.
+ format LoadIndexOp {
+ 87: lbzx({{ Rt = Mem.ub; }});
+ 279: lhzx({{ Rt = Mem.uh; }});
+ 343: lhax({{ Rt = Mem.sh; }});
+ 23: lwzx({{ Rt = Mem; }});
+ 341: lwax({{ Rt = Mem.sw; }});
+ 20: lwarx({{ Rt = Mem.sw; Rsv = 1; RsvLen = 4; RsvAddr = EA; }});
+ 535: lfsx({{ Ft.sf = Mem.sf; }});
+ 599: lfdx({{ Ft = Mem.df; }});
+ 855: lfiwax({{ Ft.uw = Mem; }});
+ }
+
+ format LoadIndexUpdateOp {
+ 119: lbzux({{ Rt = Mem.ub; }});
+ 311: lhzux({{ Rt = Mem.uh; }});
+ 375: lhaux({{ Rt = Mem.sh; }});
+ 55: lwzux({{ Rt = Mem; }});
+ 373: lwaux({{ Rt = Mem.sw; }});
+ 567: lfsux({{ Ft.sf = Mem.sf; }});
+ 631: lfdux({{ Ft = Mem.df; }});
+ }
+
+ format StoreIndexOp {
+ 215: stbx({{ Mem.ub = Rs.ub; }});
+ 407: sthx({{ Mem.uh = Rs.uh; }});
+ 151: stwx({{ Mem = Rs; }});
+ 150: stwcx({{
+ bool store_performed = false;
+ if (Rsv) {
+ if (RsvLen == 4) {
+ if (RsvAddr == EA) {
+ Mem = Rs;
+ store_performed = true;
+ }
+ }
+ }
+ Xer xer = XER;
+ Cr cr = CR;
+ cr.cr0 = ((store_performed ? 0x2 : 0x0) | xer.so);
+ CR = cr;
+ Rsv = 0;
+ }});
+ 663: stfsx({{ Mem.sf = Fs.sf; }});
+ 727: stfdx({{ Mem.df = Fs; }});
+ 983: stfiwx({{ Mem = Fs.uw; }});
+ }
+
+ format StoreIndexUpdateOp {
+ 247: stbux({{ Mem.ub = Rs.ub; }});
+ 439: sthux({{ Mem.uh = Rs.uh; }});
+ 183: stwux({{ Mem = Rs; }});
+ 695: stfsux({{ Mem.sf = Fs.sf; }});
+ 759: stfdux({{ Mem.df = Fs; }});
+ }
+
+ // These instructions all provide data cache hints
+ format MiscOp {
+ 278: dcbt({{ }});
+ 246: dcbtst({{ }});
+ 598: sync({{ }}, [ IsMemBarrier ]);
+ 854: eieio({{ }}, [ IsMemBarrier ]);
+ }
+ }
+
+ format IntImmArithCheckRaOp {
+ 14: addi({{ Rt = Ra + imm; }},
+ {{ Rt = imm }});
+ 15: addis({{ Rt = Ra + (imm << 16); }},
+ {{ Rt = imm << 16; }});
+ }
+
+ format IntImmArithOp {
+ 12: addic({{ uint32_t src = Ra; Rt = src + imm; }},
+ [computeCA]);
+ 13: addic_({{ uint32_t src = Ra; Rt = src + imm; }},
+ [computeCA, computeCR0]);
+ 8: subfic({{ int32_t src = ~Ra; Rt = src + imm + 1; }},
+ [computeCA]);
+ 7: mulli({{
+ int32_t src = Ra.sw;
+ int64_t prod = src * imm;
+ Rt = (uint32_t)prod;
+ }});
+ }
+
+ format IntImmLogicOp {
+ 24: ori({{ Ra = Rs | uimm; }});
+ 25: oris({{ Ra = Rs | (uimm << 16); }});
+ 26: xori({{ Ra = Rs ^ uimm; }});
+ 27: xoris({{ Ra = Rs ^ (uimm << 16); }});
+ 28: andi_({{ Ra = Rs & uimm; }},
+ true);
+ 29: andis_({{ Ra = Rs & (uimm << 16); }},
+ true);
+ }
+
+ 16: decode AA {
+
+ // Conditionally branch relative to PC based on CR and CTR.
+ format BranchPCRelCondCtr {
+ 0: bc({{ NPC = PC + disp; }});
+ }
+
+ // Conditionally branch to fixed address based on CR and CTR.
+ format BranchNonPCRelCondCtr {
+ 1: bca({{ NPC = targetAddr; }});
+ }
+ }
+
+ 18: decode AA {
+
+ // Unconditionally branch relative to PC.
+ format BranchPCRel {
+ 0: b({{ NPC = PC + disp; }});
+ }
+
+ // Unconditionally branch to fixed address.
+ format BranchNonPCRel {
+ 1: ba({{ NPC = targetAddr; }});
+ }
+ }
+
+ 19: decode XO_XO {
+
+ // Conditionally branch to address in LR based on CR and CTR.
+ format BranchLrCondCtr {
+ 16: bclr({{ NPC = LR & 0xfffffffc; }});
+ }
+
+ // Conditionally branch to address in CTR based on CR.
+ format BranchCtrCond {
+ 528: bcctr({{ NPC = CTR & 0xfffffffc; }});
+ }
+
+ // Condition register manipulation instructions.
+ format CondLogicOp {
+ 257: crand({{
+ uint32_t crBa = bits(CR, 31 - ba);
+ uint32_t crBb = bits(CR, 31 - bb);
+ CR = insertBits(CR, 31 - bt, crBa & crBb);
+ }});
+ 449: cror({{
+ uint32_t crBa = bits(CR, 31 - ba);
+ uint32_t crBb = bits(CR, 31 - bb);
+ CR = insertBits(CR, 31 - bt, crBa | crBb);
+ }});
+ 255: crnand({{
+ uint32_t crBa = bits(CR, 31 - ba);
+ uint32_t crBb = bits(CR, 31 - bb);
+ CR = insertBits(CR, 31 - bt, !(crBa & crBb));
+ }});
+ 193: crxor({{
+ uint32_t crBa = bits(CR, 31 - ba);
+ uint32_t crBb = bits(CR, 31 - bb);
+ CR = insertBits(CR, 31 - bt, crBa ^ crBb);
+ }});
+ 33: crnor({{
+ uint32_t crBa = bits(CR, 31 - ba);
+ uint32_t crBb = bits(CR, 31 - bb);
+ CR = insertBits(CR, 31 - bt, !(crBa | crBb));
+ }});
+ 289: creqv({{
+ uint32_t crBa = bits(CR, 31 - ba);
+ uint32_t crBb = bits(CR, 31 - bb);
+ CR = insertBits(CR, 31 - bt, crBa == crBb);
+ }});
+ 129: crandc({{
+ uint32_t crBa = bits(CR, 31 - ba);
+ uint32_t crBb = bits(CR, 31 - bb);
+ CR = insertBits(CR, 31 - bt, crBa & !crBb);
+ }});
+ 417: crorc({{
+ uint32_t crBa = bits(CR, 31 - ba);
+ uint32_t crBb = bits(CR, 31 - bb);
+ CR = insertBits(CR, 31 - bt, crBa | !crBb);
+ }});
+ }
+ format CondMoveOp {
+ 0: mcrf({{
+ uint32_t crBfa = bits(CR, 31 - bfa*4, 28 - bfa*4);
+ CR = insertBits(CR, 31 - bf*4, 28 - bf*4, crBfa);
+ }});
+ }
+ format MiscOp {
+ 150: isync({{ }}, [ IsSerializeAfter ]);
+ }
+ }
+
+ format IntRotateOp {
+ 21: rlwinm({{ Ra = rotateValue(Rs, sh) & fullMask; }});
+ 23: rlwnm({{ Ra = rotateValue(Rs, Rb) & fullMask; }});
+ 20: rlwimi({{ Ra = (rotateValue(Rs, sh) & fullMask) | (Ra & ~fullMask); }});
+ }
+
+ format LoadDispOp {
+ 34: lbz({{ Rt = Mem.ub; }});
+ 40: lhz({{ Rt = Mem.uh; }});
+ 42: lha({{ Rt = Mem.sh; }});
+ 32: lwz({{ Rt = Mem; }});
+ 58: lwa({{ Rt = Mem.sw; }},
+ {{ EA = Ra + (disp & 0xfffffffc); }},
+ {{ EA = disp & 0xfffffffc; }});
+ 48: lfs({{ Ft.sf = Mem.sf; }});
+ 50: lfd({{ Ft = Mem.df; }});
+ }
+
+ format LoadDispUpdateOp {
+ 35: lbzu({{ Rt = Mem.ub; }});
+ 41: lhzu({{ Rt = Mem.uh; }});
+ 43: lhau({{ Rt = Mem.sh; }});
+ 33: lwzu({{ Rt = Mem; }});
+ 49: lfsu({{ Ft.sf = Mem.sf; }});
+ 51: lfdu({{ Ft = Mem.df; }});
+ }
+
+ format StoreDispOp {
+ 38: stb({{ Mem.ub = Rs.ub; }});
+ 44: sth({{ Mem.uh = Rs.uh; }});
+ 36: stw({{ Mem = Rs; }});
+ 52: stfs({{ Mem.sf = Fs.sf; }});
+ 54: stfd({{ Mem.df = Fs; }});
+ }
+
+ format StoreDispUpdateOp {
+ 39: stbu({{ Mem.ub = Rs.ub; }});
+ 45: sthu({{ Mem.uh = Rs.uh; }});
+ 37: stwu({{ Mem = Rs; }});
+ 53: stfsu({{ Mem.sf = Fs.sf; }});
+ 55: stfdu({{ Mem.df = Fs; }});
+ }
+
+ 17: IntOp::sc({{ xc->syscall(R0); }},
+ [ IsSyscall, IsNonSpeculative, IsSerializeAfter ]);
+
+ format FloatArithOp {
+ 59: decode A_XO {
+ 21: fadds({{ Ft = Fa + Fb; }});
+ 20: fsubs({{ Ft = Fa - Fb; }});
+ 25: fmuls({{ Ft = Fa * Fc; }});
+ 18: fdivs({{ Ft = Fa / Fb; }});
+ 29: fmadds({{ Ft = (Fa * Fc) + Fb; }});
+ 28: fmsubs({{ Ft = (Fa * Fc) - Fb; }});
+ 31: fnmadds({{ Ft = -((Fa * Fc) + Fb); }});
+ 30: fnmsubs({{ Ft = -((Fa * Fc) - Fb); }});
+ }
+ }
+
+ 63: decode A_XO {
+ format FloatArithOp {
+ 21: fadd({{ Ft = Fa + Fb; }});
+ 20: fsub({{ Ft = Fa - Fb; }});
+ 25: fmul({{ Ft = Fa * Fc; }});
+ 18: fdiv({{ Ft = Fa / Fb; }});
+ 29: fmadd({{ Ft = (Fa * Fc) + Fb; }});
+ 28: fmsub({{ Ft = (Fa * Fc) - Fb; }});
+ 31: fnmadd({{ Ft = -((Fa * Fc) + Fb); }});
+ 30: fnmsub({{ Ft = -((Fa * Fc) - Fb); }});
+ }
+
+ default: decode XO_XO {
+ format FloatConvertOp {
+ 12: frsp({{ Ft.sf = Fb; }});
+ 15: fctiwz({{ Ft.sw = (int32_t)trunc(Fb); }});
+ }
+
+ format FloatOp {
+ 0: fcmpu({{
+ uint32_t c = makeCRField(Fa, Fb);
+ Fpscr fpscr = FPSCR;
+ fpscr.fprf.fpcc = c;
+ FPSCR = fpscr;
+ CR = insertCRField(CR, BF, c);
+ }});
+ }
+
+ format FloatRCCheckOp {
+ 72: fmr({{ Ft = Fb; }});
+ 264: fabs({{
+ Ft.uq = Fb.uq;
+ Ft.uq = insertBits(Ft.uq, 63, 0); }});
+ 136: fnabs({{
+ Ft.uq = Fb.uq;
+ Ft.uq = insertBits(Ft.uq, 63, 1); }});
+ 40: fneg({{ Ft = -Fb; }});
+ 8: fcpsgn({{
+ Ft.uq = Fb.uq;
+ Ft.uq = insertBits(Ft.uq, 63, Fa.uq<63:63>);
+ }});
+ 583: mffs({{ Ft.uq = FPSCR; }});
+ 134: mtfsfi({{
+ FPSCR = insertCRField(FPSCR, BF + (8 * (1 - W)), U_FIELD);
+ }});
+ 711: mtfsf({{
+ if (L == 1) { FPSCR = Fb.uq; }
+ else {
+ for (int i = 0; i < 8; ++i) {
+ if (bits(FLM, i) == 1) {
+ int k = 4 * (i + (8 * (1 - W)));
+ FPSCR = insertBits(FPSCR, k, k + 3,
+ bits(Fb.uq, k, k + 3));
+ }
+ }
+ }
+ }});
+ 70: mtfsb0({{ FPSCR = insertBits(FPSCR, 31 - BT, 0); }});
+ 38: mtfsb1({{ FPSCR = insertBits(FPSCR, 31 - BT, 1); }});
+ }
+ }
+ }
+}
diff --git a/src/arch/power/isa/formats/basic.isa b/src/arch/power/isa/formats/basic.isa
new file mode 100644
index 000000000..adb5e7ef8
--- /dev/null
+++ b/src/arch/power/isa/formats/basic.isa
@@ -0,0 +1,103 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2009 The University of Edinburgh
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Timothy M. Jones
+
+// Declarations for execute() methods.
+def template BasicExecDeclare {{
+ Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+// Basic instruction class declaration template.
+def template BasicDeclare {{
+ /**
+ * Static instruction class for "%(mnemonic)s".
+ */
+ class %(class_name)s : public %(base_class)s
+ {
+ public:
+ /// Constructor.
+ %(class_name)s(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ };
+}};
+
+// Basic instruction class constructor template.
+def template BasicConstructor {{
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
+ {
+ %(constructor)s;
+ }
+}};
+
+
+// Basic instruction class execute method template.
+def template BasicExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+
+ %(op_decl)s;
+ %(op_rd)s;
+ %(code)s;
+
+ if (fault == NoFault)
+ {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+// Basic decode template.
+def template BasicDecode {{
+ return new %(class_name)s(machInst);
+}};
+
+// Basic decode template, passing mnemonic in as string arg to constructor.
+def template BasicDecodeWithMnemonic {{
+ return new %(class_name)s("%(mnemonic)s", machInst);
+}};
+
+// Definitions of execute methods that panic.
+def template BasicExecPanic {{
+Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
+{
+ panic("Execute method called when it shouldn't!");
+}
+}};
+
+// The most basic instruction format...
+def format BasicOp(code, *flags) {{
+ iop = InstObjParams(name, Name, 'PowerStaticInst', code, flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
diff --git a/src/arch/power/isa/formats/branch.isa b/src/arch/power/isa/formats/branch.isa
new file mode 100644
index 000000000..d51ed5c25
--- /dev/null
+++ b/src/arch/power/isa/formats/branch.isa
@@ -0,0 +1,222 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2009 The University of Edinburgh
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Timothy M. Jones
+
+////////////////////////////////////////////////////////////////////
+//
+// Control transfer instructions
+//
+// From the Power ISA Book I v2.06, page 33, the following rules should
+// be obeyed by programmers:
+//
+// - Use branch instructions where LK == 1 only as subroutine calls.
+// - Pair each subroutine call with a bclr instruction with BH == 00
+// that returns from the subroutine.
+// - Do not use bclrl as a subroutine call.
+//
+// Therefore, I've flagged all versions that update the link register (LR)
+// as calls, except bclrl (BranchLrCtrCond format) which is flagged as
+// a return.
+
+
+let {{
+
+# Simple code to update link register (LR).
+updateLrCode = 'LR = PC + 4;'
+
+}};
+
+// Instructions that unconditionally branch relative to the current PC.
+def format BranchPCRel(br_code, inst_flags = []) {{
+ inst_flags += ('IsUncondControl', 'IsDirectControl')
+ basic_code = br_code
+
+ # The version that does not update LR
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'BranchPCRel', basic_code, inst_flags,
+ CheckLkDecode, BasicConstructor)
+
+ # The version that does the update
+ update_code = basic_code + updateLrCode
+ update_flags = inst_flags + [ 'IsCall' ]
+ (header_output_up, decoder_output_up, _, exec_output_up) = \
+ GenAluOp(name, Name + 'UpdateLr', 'BranchPCRel', update_code,
+ update_flags, CheckLkDecode, BasicConstructor)
+
+ # Add the outputs together
+ header_output += header_output_up
+ decoder_output += decoder_output_up
+ exec_output += exec_output_up
+}};
+
+// Instructions that unconditionally branch to a specific address.
+def format BranchNonPCRel(br_code, inst_flags = []) {{
+ inst_flags += ('IsUncondControl', 'IsDirectControl')
+ basic_code = br_code
+
+ # The version that does not update LR
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'BranchNonPCRel', basic_code, inst_flags,
+ CheckLkDecode, BasicConstructor)
+
+ # The version that does the update
+ update_code = basic_code + updateLrCode
+ update_flags = inst_flags + [ 'IsCall' ]
+ (header_output_up, decoder_output_up, _, exec_output_up) = \
+ GenAluOp(name, Name + 'UpdateLr', 'BranchNonPCRel', update_code,
+ update_flags, CheckLkDecode, BasicConstructor)
+
+ # Add the outputs together
+ header_output += header_output_up
+ decoder_output += decoder_output_up
+ exec_output += exec_output_up
+}};
+
+let {{
+
+# Check the condition register (CR) allows the branch to be taken.
+def GetCondCode(br_code):
+ cond_code = 'if(condOk(CR)) {\n'
+ cond_code += ' ' + br_code + '\n'
+ cond_code += '} else {\n'
+ cond_code += ' NPC = NPC;\n'
+ cond_code += '}\n'
+ return cond_code
+
+# Check the condition register (CR) and count register (CTR) allow the
+# branch to be taken. Also, in certain situations, decrement the count
+# register too. This takes place in ctrOk within BranchCond classes.
+def GetCtrCondCode(br_code):
+ cond_code = 'uint32_t ctr = CTR;\n'
+ cond_code += 'bool ctr_ok = ctrOk(ctr);\n'
+ cond_code += 'bool cond_ok = condOk(CR);\n'
+ cond_code += 'if(ctr_ok && cond_ok) {\n'
+ cond_code += ' ' + br_code + '\n'
+ cond_code += '} else {\n'
+ cond_code += ' NPC = NPC;\n'
+ cond_code += '}\n'
+ cond_code += 'CTR = ctr;\n'
+ return cond_code
+
+}};
+
+// Instructions that conditionally branch relative to the current PC based on
+// the condition register (CR) and count register (CTR).
+def format BranchPCRelCondCtr(br_code, inst_flags = []) {{
+ inst_flags += ('IsCondControl', 'IsDirectControl')
+ basic_code = GetCtrCondCode(br_code)
+
+ # The version that does not update LR
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'BranchPCRelCond', basic_code, inst_flags,
+ CheckLkDecode, BasicConstructor)
+
+ # The version that does the update
+ update_code = basic_code + updateLrCode
+ update_flags = inst_flags + [ 'IsCall' ]
+ (header_output_up, decoder_output_up, _, exec_output_up) = \
+ GenAluOp(name, Name + 'UpdateLr', 'BranchPCRelCond', update_code,
+ update_flags, CheckLkDecode, BasicConstructor)
+
+ # Add the outputs together
+ header_output += header_output_up
+ decoder_output += decoder_output_up
+ exec_output += exec_output_up
+}};
+
+// Instructions that conditionally branch to a specific address based on the
+// condition register (CR) and count register (CTR).
+def format BranchNonPCRelCondCtr(br_code, inst_flags = []) {{
+ inst_flags += ('IsCondControl', 'IsDirectControl')
+ basic_code = GetCtrCondCode(br_code)
+
+ # The version that does not update LR
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'BranchNonPCRelCond', basic_code, inst_flags,
+ CheckLkDecode, BasicConstructor)
+
+ # The version that does the update
+ update_code = basic_code + updateLrCode
+ update_flags = inst_flags + [ 'IsCall' ]
+ (header_output_up, decoder_output_up, _, exec_output_up) = \
+ GenAluOp(name, Name + 'UpdateLr', 'BranchNonPCRelCond', update_code,
+ update_flags, CheckLkDecode, BasicConstructor)
+
+ # Add the outputs together
+ header_output += header_output_up
+ decoder_output += decoder_output_up
+ exec_output += exec_output_up
+}};
+
+// Instructions that conditionally branch to the address in the link register
+// (LR) based on the condition register (CR) and count register (CTR).
+def format BranchLrCondCtr(br_code, inst_flags = []) {{
+ inst_flags += ('IsCondControl', 'IsIndirectControl', 'IsReturn')
+ basic_code = GetCtrCondCode(br_code)
+
+ # The version that does not update LR
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'BranchRegCond', basic_code, inst_flags,
+ CheckLkDecode, BasicConstructor)
+
+ # The version that does the update
+ update_code = basic_code + updateLrCode
+ (header_output_up, decoder_output_up, _, exec_output_up) = \
+ GenAluOp(name, Name + 'UpdateLr', 'BranchRegCond', update_code,
+ inst_flags, CheckLkDecode, BasicConstructor)
+
+ # Add the outputs together
+ header_output += header_output_up
+ decoder_output += decoder_output_up
+ exec_output += exec_output_up
+}};
+
+// Instructions that conditionally branch to the address in the count register
+// (CTR) based on the condition register (CR).
+def format BranchCtrCond(br_code, inst_flags = []) {{
+ inst_flags += ('IsCondControl', 'IsIndirectControl')
+ basic_code = GetCondCode(br_code)
+
+ # The version that does not update LR
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'BranchRegCond', basic_code, inst_flags,
+ CheckLkDecode, BasicConstructor)
+
+ # The version that does the update
+ update_code = basic_code + updateLrCode
+ update_flags = inst_flags + [ 'IsCall' ]
+ (header_output_up, decoder_output_up, _, exec_output_up) = \
+ GenAluOp(name, Name + 'UpdateLr', 'BranchRegCond', update_code,
+ update_flags, CheckLkDecode, BasicConstructor)
+
+ # Add the outputs together
+ header_output += header_output_up
+ decoder_output += decoder_output_up
+ exec_output += exec_output_up
+}};
diff --git a/src/arch/power/isa/formats/condition.isa b/src/arch/power/isa/formats/condition.isa
new file mode 100644
index 000000000..12ee7ae7d
--- /dev/null
+++ b/src/arch/power/isa/formats/condition.isa
@@ -0,0 +1,47 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2009 The University of Edinburgh
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Timothy M. Jones
+
+// Logical instructions that manipulate the condition register
+def format CondLogicOp(code, *flags) {{
+ iop = InstObjParams(name, Name, 'CondLogicOp', code, flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
+// Instructions that condition register fields
+def format CondMoveOp(code, *flags) {{
+ iop = InstObjParams(name, Name, 'CondMoveOp', code, flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
diff --git a/src/arch/power/isa/formats/formats.isa b/src/arch/power/isa/formats/formats.isa
new file mode 100644
index 000000000..ec2575196
--- /dev/null
+++ b/src/arch/power/isa/formats/formats.isa
@@ -0,0 +1,60 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2009 The University of Edinburgh
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Timothy M. Jones
+
+//Templates from this format are used later
+//Include the basic format
+##include "basic.isa"
+
+//Include integer instructions
+##include "integer.isa"
+
+//Include condition register instructions
+##include "condition.isa"
+
+//Include utility functions
+##include "util.isa"
+
+//Include the float formats
+##include "fp.isa"
+
+//Include the mem format
+##include "mem.isa"
+
+//Include the branch format
+##include "branch.isa"
+
+//Include the misc format
+##include "misc.isa"
+
+//Include the unimplemented format
+##include "unimp.isa"
+
+//Include the unknown format
+##include "unknown.isa"
diff --git a/src/arch/power/isa/formats/fp.isa b/src/arch/power/isa/formats/fp.isa
new file mode 100644
index 000000000..db917476e
--- /dev/null
+++ b/src/arch/power/isa/formats/fp.isa
@@ -0,0 +1,132 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2009 The University of Edinburgh
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Timothy M. Jones
+
+////////////////////////////////////////////////////////////////////
+//
+// Floating Point operate instructions
+//
+
+
+let {{
+
+ readFPSCRCode = 'Fpscr fpscr = FPSCR;'
+
+ computeCR1Code = '''
+ Cr cr = CR;
+ cr.cr1 = (fpscr.fx << 3) | (fpscr.fex << 2) |
+ (fpscr.vx << 1) | fpscr.ox;
+ CR = cr;
+ '''
+
+}};
+
+// Primary format for floating point operate instructions:
+def format FloatOp(code, inst_flags = []) {{
+ iop = InstObjParams(name, Name, 'FloatOp',
+ {"code": code},
+ inst_flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
+// Floating point operations that compute the CR1 code if RC is set. No other
+// special registers are touched using these operations.
+def format FloatRCCheckOp(code, inst_flags = []) {{
+
+ # Code when Rc is set
+ code_rc1 = code + readFPSCRCode + computeCR1Code
+
+ # Generate the first class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'FloatOp', code, inst_flags,
+ CheckRcDecode, BasicConstructor)
+
+ # Generate the second class
+ (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
+ GenAluOp(name, Name + 'RcSet', 'FloatOp', code_rc1, inst_flags,
+ CheckRcDecode, IntRcConstructor)
+
+ # Finally, add to the other outputs
+ header_output += header_output_rc1
+ decoder_output += decoder_output_rc1
+ exec_output += exec_output_rc1
+}};
+
+// Floating point elementary arithmetic operations. Besides having two
+// versions of each instruction for when Rc is set or not, we also have
+// to alter lots of special registers depending on the result of the
+// operation. The result is always in Ft.sf.
+def format FloatArithOp(code, inst_flags = []) {{
+
+ # Code when Rc is set
+ code_rc1 = code + readFPSCRCode + computeCR1Code
+
+ # Generate the first class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'FloatOp', code, inst_flags,
+ CheckRcDecode, BasicConstructor)
+
+ # Generate the second class
+ (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
+ GenAluOp(name, Name + 'RcSet', 'FloatOp', code_rc1, inst_flags,
+ CheckRcDecode, IntRcConstructor)
+
+ # Finally, add to the other outputs
+ header_output += header_output_rc1
+ decoder_output += decoder_output_rc1
+ exec_output += exec_output_rc1
+}};
+
+// Floating point rounding and conversion operations. Besides having two
+// versions of each instruction for when Rc is set or not, we also have
+// to alter lots of special registers depending on the result of the
+// operation. The result is always in Ft.sf.
+def format FloatConvertOp(code, inst_flags = []) {{
+
+ # Code when Rc is set
+ code_rc1 = code + readFPSCRCode + computeCR1Code
+
+ # Generate the first class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'FloatOp', code, inst_flags,
+ CheckRcDecode, BasicConstructor)
+
+ # Generate the second class
+ (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
+ GenAluOp(name, Name + 'RcSet', 'FloatOp', code_rc1, inst_flags,
+ CheckRcDecode, IntRcConstructor)
+
+ # Finally, add to the other outputs
+ header_output += header_output_rc1
+ decoder_output += decoder_output_rc1
+ exec_output += exec_output_rc1
+}};
diff --git a/src/arch/power/isa/formats/integer.isa b/src/arch/power/isa/formats/integer.isa
new file mode 100644
index 000000000..0766826ec
--- /dev/null
+++ b/src/arch/power/isa/formats/integer.isa
@@ -0,0 +1,369 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2009 The University of Edinburgh
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Timothy M. Jones
+
+////////////////////////////////////////////////////////////////////
+//
+// Integer ALU instructions
+//
+
+
+// Instruction class constructor template when Rc is set.
+def template IntRcConstructor {{
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
+ {
+ %(constructor)s;
+ rcSet = true;
+ }
+}};
+
+
+// Instruction class constructor template when OE is set.
+def template IntOeConstructor {{
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
+ {
+ %(constructor)s;
+ oeSet = true;
+ }
+}};
+
+
+// Instruction class constructor template when both Rc and OE are set.
+def template IntRcOeConstructor {{
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
+ {
+ %(constructor)s;
+ rcSet = true;
+ oeSet = true;
+ }
+}};
+
+
+let {{
+
+readXERCode = 'Xer xer = XER;'
+
+setXERCode = 'XER = xer;'
+
+computeCR0Code = '''
+ Cr cr = CR;
+ cr.cr0 = makeCRField((int32_t)%(result)s, (int32_t)0, xer.so);
+ CR = cr;
+'''
+
+computeCACode = '''
+ if (findCarry(32, %(result)s, %(inputa)s, %(inputb)s)) {
+ xer.ca = 1;
+ } else {
+ xer.ca = 0;
+ }
+'''
+
+computeOVCode = '''
+ if (findOverflow(32, %(result)s, %(inputa)s, %(inputb)s)) {
+ xer.ov = 1;
+ xer.so = 1;
+ } else {
+ xer.ov = 0;
+ }
+'''
+
+computeDivOVCode = '''
+ if (divSetOV) {
+ xer.ov = 1;
+ xer.so = 1;
+ } else {
+ if (findOverflow(32, %(result)s, %(inputa)s, %(inputb)s)) {
+ xer.ov = 1;
+ xer.so = 1;
+ } else {
+ xer.ov = 0;
+ }
+ }
+'''
+
+}};
+
+
+// A basic integer instruction.
+def format IntOp(code, inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntOp', code, inst_flags, BasicDecode,
+ BasicConstructor)
+}};
+
+
+// Integer instructions with immediate (signed or unsigned).
+def format IntImmOp(code, inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode,
+ BasicConstructor)
+}};
+
+
+// Integer instructions with immediate that perform arithmetic.
+// These instructions all write to Rt and use an altered form of the
+// value in source register Ra, hence the use of src to hold the actual
+// value. The control flags include the use of code to compute the
+// carry bit or the CR0 code.
+def format IntImmArithOp(code, ctrl_flags = [], inst_flags = []) {{
+
+ # Set up the dictionary and deal with control flags
+ dict = {'result':'Rt', 'inputa':'src', 'inputb':'imm'}
+ if ctrl_flags:
+ code += readXERCode
+ for val in ctrl_flags:
+ if val == 'computeCA':
+ code += computeCACode % dict + setXERCode
+ elif val == 'computeCR0':
+ code += computeCR0Code % dict
+
+ # Generate the class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode,
+ BasicConstructor)
+}};
+
+
+// Integer instructions with immediate that perform arithmetic but use
+// the value 0 when Ra == 0. We generate two versions of each instruction
+// corresponding to these two different scenarios. The correct version is
+// determined at decode (see the CheckRaDecode template).
+def format IntImmArithCheckRaOp(code, code_ra0, inst_flags = []) {{
+
+ # First the version where Ra is non-zero
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntImmOp', code, inst_flags,
+ CheckRaDecode, BasicConstructor)
+
+ # Now another version where Ra == 0
+ (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \
+ GenAluOp(name, Name + 'RaZero', 'IntImmOp', code_ra0, inst_flags,
+ CheckRaDecode, BasicConstructor)
+
+ # Finally, add to the other outputs
+ header_output += header_output_ra0
+ decoder_output += decoder_output_ra0
+ exec_output += exec_output_ra0
+}};
+
+
+// Integer instructions with immediate that perform logic operations.
+// All instructions write to Ra and use Rs as a source register. Some
+// also compute the CR0 code too.
+def format IntImmLogicOp(code, computeCR0 = 0, inst_flags = []) {{
+
+ # Set up the dictionary and deal with computing CR0
+ dict = {'result':'Ra'}
+ if computeCR0:
+ code += readXERCode + computeCR0Code % dict
+
+ # Generate the class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode,
+ BasicConstructor)
+}};
+
+
+// Integer instructions that perform logic operations. The result is
+// always written into Ra. All instructions have 2 versions depending on
+// whether the Rc bit is set to compute the CR0 code. This is determined
+// at decode as before.
+def format IntLogicOp(code, inst_flags = []) {{
+ dict = {'result':'Ra'}
+
+ # Code when Rc is set
+ code_rc1 = code + readXERCode + computeCR0Code % dict
+
+ # Generate the first class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntOp', code, inst_flags,
+ CheckRcDecode, BasicConstructor)
+
+ # Generate the second class
+ (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
+ GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags,
+ CheckRcDecode, IntRcConstructor)
+
+ # Finally, add to the other outputs
+ header_output += header_output_rc1
+ decoder_output += decoder_output_rc1
+ exec_output += exec_output_rc1
+}};
+
+
+// Integer instructions with a shift amount. As above, except inheriting
+// from the IntShiftOp class.
+def format IntShiftOp(code, inst_flags = []) {{
+ dict = {'result':'Ra'}
+
+ # Code when Rc is set
+ code_rc1 = code + readXERCode + computeCR0Code % dict
+
+ # Generate the first class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntShiftOp', code, inst_flags,
+ CheckRcDecode, BasicConstructor)
+
+ # Generate the second class
+ (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
+ GenAluOp(name, Name + 'RcSet', 'IntShiftOp', code_rc1, inst_flags,
+ CheckRcDecode, IntRcConstructor)
+
+ # Finally, add to the other outputs
+ header_output += header_output_rc1
+ decoder_output += decoder_output_rc1
+ exec_output += exec_output_rc1
+}};
+
+
+// Instructions in this format are all reduced to the form Rt = src1 + src2,
+// therefore we just give src1 and src2 definitions. In working out the
+// template we first put in the definitions of the variables and then
+// the code for the addition. We also deal with computing the carry flag
+// if required.
+//
+// We generate 4 versions of each instruction. This correspond to the
+// different combinations of having the OE bit set or unset (which controls
+// whether the overflow flag is computed) and the Rc bit set or unset too
+// (which controls whether the CR0 code is computed).
+def format IntSumOp(src1, src2, ca = {{ 0 }}, computeCA = 0,
+ inst_flags = []) {{
+
+ # The result is always in Rt, but the source values vary
+ dict = {'result':'Rt', 'inputa':'src1', 'inputb':'src2'}
+
+ # Add code to set up variables and do the sum
+ code = 'uint32_t src1 = ' + src1 + ';\n'
+ code += 'uint32_t src2 = ' + src2 + ';\n'
+ code += 'uint32_t ca = ' + ca + ';\n'
+ code += 'Rt = src1 + src2 + ca;\n'
+
+ # Add code for calculating the carry, if needed
+ if computeCA:
+ code += computeCACode % dict + setXERCode
+
+ # Setup the 4 code versions and add code to access XER if necessary
+ code_rc1 = readXERCode + code
+ code_oe1 = readXERCode + code + computeOVCode % dict + setXERCode
+ code_rc1_oe1 = readXERCode + code + computeOVCode % dict + setXERCode
+ if (computeCA or ca == 'xer.ca'):
+ code = readXERCode + code
+ code_rc1 += computeCR0Code % dict
+ code_rc1_oe1 += computeCR0Code % dict
+
+ # Generate the classes
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntOp', code, inst_flags,
+ CheckRcOeDecode, BasicConstructor)
+ (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
+ GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags,
+ CheckRcOeDecode, IntRcConstructor)
+ (header_output_oe1, decoder_output_oe1, _, exec_output_oe1) = \
+ GenAluOp(name, Name + 'OeSet', 'IntOp', code_oe1, inst_flags,
+ CheckRcOeDecode, IntOeConstructor)
+ (header_output_rc1_oe1, decoder_output_rc1_oe1, _, exec_output_rc1_oe1) = \
+ GenAluOp(name, Name + 'RcSetOeSet', 'IntOp', code_rc1_oe1,
+ inst_flags, CheckRcOeDecode, IntRcOeConstructor)
+
+ # Finally, add to the other outputs
+ header_output += \
+ header_output_rc1 + header_output_oe1 + header_output_rc1_oe1
+ decoder_output += \
+ decoder_output_rc1 + decoder_output_oe1 + decoder_output_rc1_oe1
+ exec_output += \
+ exec_output_rc1 + exec_output_oe1 + exec_output_rc1_oe1
+
+}};
+
+
+// Instructions that use source registers Ra and Rb, with the result
+// placed into Rt. Basically multiply and divide instructions. The
+// carry bit is never set, but overflow can be calculated. Division
+// explicitly sets the overflow bit in certain situations and this is
+// dealt with using the 'divSetOV' boolean in decoder.isa. We generate
+// two versions of each instruction to deal with the Rc bit.
+def format IntArithOp(code, computeOV = 0, inst_flags = []) {{
+
+ # The result is always in Rt, but the source values vary
+ dict = {'result':'Rt', 'inputa':'src1', 'inputb':'src2'}
+
+ # Deal with setting the overflow flag
+ if computeOV:
+ code = 'bool divSetOV = false;\n' + code
+ code += computeDivOVCode % dict + setXERCode
+
+ # Setup the 2 code versions and add code to access XER if necessary
+ code_rc1 = readXERCode + code + computeCR0Code % dict
+ if computeOV:
+ code = readXERCode + code
+
+ # Generate the classes
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntOp', code, inst_flags,
+ CheckRcDecode, BasicConstructor)
+
+ # Generate the second class
+ (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
+ GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags,
+ CheckRcDecode, IntRcConstructor)
+
+ # Finally, add to the other outputs
+ header_output += header_output_rc1
+ decoder_output += decoder_output_rc1
+ exec_output += exec_output_rc1
+}};
+
+
+// A special format for rotate instructions which use certain fields
+// from the instruction's binary encoding. We need two versions for each
+// instruction to deal with the Rc bit.
+def format IntRotateOp(code, inst_flags = []) {{
+
+ # The result is always in Ra
+ dict = {'result':'Ra'}
+
+ # Setup the code for when Rc is set
+ code_rc1 = readXERCode + code + computeCR0Code % dict
+
+ # Generate the first class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntRotateOp', code, inst_flags,
+ CheckRcDecode, BasicConstructor)
+
+ # Generate the second class
+ (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
+ GenAluOp(name, Name + 'RcSet', 'IntRotateOp', code_rc1, inst_flags,
+ CheckRcDecode, IntRcConstructor)
+
+ # Finally, add to the other outputs
+ header_output += header_output_rc1
+ decoder_output += decoder_output_rc1
+ exec_output += exec_output_rc1
+}};
diff --git a/src/arch/power/isa/formats/mem.isa b/src/arch/power/isa/formats/mem.isa
new file mode 100644
index 000000000..1be49c2f7
--- /dev/null
+++ b/src/arch/power/isa/formats/mem.isa
@@ -0,0 +1,351 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2009 The University of Edinburgh
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Timothy M. Jones
+
+////////////////////////////////////////////////////////////////////
+//
+// Memory-format instructions
+//
+
+def template LoadStoreDeclare {{
+ /**
+ * Static instruction class for "%(mnemonic)s".
+ */
+ class %(class_name)s : public %(base_class)s
+ {
+ public:
+
+ /// Constructor.
+ %(class_name)s(ExtMachInst machInst);
+
+ %(BasicExecDeclare)s
+
+ %(InitiateAccDeclare)s
+
+ %(CompleteAccDeclare)s
+ };
+}};
+
+
+def template InitiateAccDeclare {{
+ Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+
+def template CompleteAccDeclare {{
+ Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+
+def template LoadStoreConstructor {{
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
+ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
+ {
+ %(constructor)s;
+ }
+}};
+
+
+def template LoadExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+def template LoadInitiateAcc {{
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(op_src_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
+ xc->setEA(EA);
+ }
+
+ return fault;
+ }
+}};
+
+
+def template LoadCompleteAcc {{
+ Fault %(class_name)s::completeAcc(PacketPtr pkt,
+ %(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+ uint%(mem_acc_size)d_t val;
+
+ %(op_decl)s;
+ %(op_rd)s;
+
+ EA = xc->getEA();
+
+ val = pkt->get<uint%(mem_acc_size)d_t>();
+ *((uint%(mem_acc_size)d_t*)&Mem) = val;
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+def template StoreExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+ memAccessFlags, NULL);
+ if (traceData) { traceData->setData(Mem); }
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+def template StoreInitiateAcc {{
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+ memAccessFlags, NULL);
+ if (traceData) { traceData->setData(Mem); }
+ }
+
+ // Need to write back any potential address register update
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+def template StoreCompleteAcc {{
+ Fault %(class_name)s::completeAcc(PacketPtr pkt,
+ %(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+
+ %(op_dest_decl)s;
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+// The generic memory operation generator. This is called when two versions
+// of an instruction are needed - when Ra == 0 and otherwise. This is so
+// that instructions can use the value 0 when Ra == 0 but avoid having a
+// dependence on Ra.
+let {{
+
+def GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base,
+ load_or_store, mem_flags = [], inst_flags = []):
+
+ # First the version where Ra is non-zero
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ base_class = base,
+ decode_template = CheckRaDecode,
+ exec_template_base = load_or_store)
+
+ # Now another version where Ra == 0
+ (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \
+ LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code,
+ mem_flags, inst_flags,
+ base_class = base,
+ exec_template_base = load_or_store)
+
+ # Finally, add to the other outputs
+ header_output += header_output_ra0
+ decoder_output += decoder_output_ra0
+ exec_output += exec_output_ra0
+ return (header_output, decoder_output, decode_block, exec_output)
+
+}};
+
+
+def format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
+ ea_code_ra0 = {{ EA = Rb; }},
+ mem_flags = [], inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
+ 'MemOp', 'Load', mem_flags, inst_flags)
+}};
+
+
+def format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
+ ea_code_ra0 = {{ EA = Rb; }},
+ mem_flags = [], inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
+ 'MemOp', 'Store', mem_flags, inst_flags)
+}};
+
+
+def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
+ mem_flags = [], inst_flags = []) {{
+
+ # Add in the update code
+ memacc_code += 'Ra = EA;'
+
+ # Generate the class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ base_class = 'MemOp',
+ exec_template_base = 'Load')
+}};
+
+
+def format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
+ mem_flags = [], inst_flags = []) {{
+
+ # Add in the update code
+ memacc_code += 'Ra = EA;'
+
+ # Generate the class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ base_class = 'MemOp',
+ exec_template_base = 'Store')
+}};
+
+
+def format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
+ ea_code_ra0 = {{ EA = disp; }},
+ mem_flags = [], inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
+ 'MemDispOp', 'Load', mem_flags, inst_flags)
+}};
+
+
+def format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
+ ea_code_ra0 = {{ EA = disp; }},
+ mem_flags = [], inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
+ 'MemDispOp', 'Store', mem_flags, inst_flags)
+}};
+
+
+def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
+ mem_flags = [], inst_flags = []) {{
+
+ # Add in the update code
+ memacc_code += 'Ra = EA;'
+
+ # Generate the class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ base_class = 'MemDispOp',
+ exec_template_base = 'Load')
+}};
+
+
+def format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
+ mem_flags = [], inst_flags = []) {{
+
+ # Add in the update code
+ memacc_code += 'Ra = EA;'
+
+ # Generate the class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ base_class = 'MemDispOp',
+ exec_template_base = 'Store')
+}};
diff --git a/src/arch/power/isa/formats/misc.isa b/src/arch/power/isa/formats/misc.isa
new file mode 100644
index 000000000..93536aa18
--- /dev/null
+++ b/src/arch/power/isa/formats/misc.isa
@@ -0,0 +1,61 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2009 The University of Edinburgh
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Timothy M. Jones
+
+////////////////////////////////////////////////////////////////////
+//
+// Misc instructions
+//
+
+def template MiscOpExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+ %(op_decl)s;
+ %(op_rd)s;
+
+ %(code)s;
+ if (fault == NoFault)
+ {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+def format MiscOp(code, opt_flags = []) {{
+ iop = InstObjParams(name, Name, 'IntOp',
+ {"code": code},
+ opt_flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = MiscOpExecute.subst(iop)
+}};
diff --git a/src/arch/power/isa/formats/unimp.isa b/src/arch/power/isa/formats/unimp.isa
new file mode 100644
index 000000000..60a7c469d
--- /dev/null
+++ b/src/arch/power/isa/formats/unimp.isa
@@ -0,0 +1,146 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007-2008 The Florida State University
+// Copyright (c) 2009 The University of Edinburgh
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Stephen Hines
+// Timothy M. Jones
+
+////////////////////////////////////////////////////////////////////
+//
+// Unimplemented instructions
+//
+
+output header {{
+ /**
+ * Static instruction class for unimplemented instructions that
+ * cause simulator termination. Note that these are recognized
+ * (legal) instructions that the simulator does not support; the
+ * 'Unknown' class is used for unrecognized/illegal instructions.
+ * This is a leaf class.
+ */
+ class FailUnimplemented : public PowerStaticInst
+ {
+ public:
+ /// Constructor
+ FailUnimplemented(const char *_mnemonic, MachInst _machInst)
+ : PowerStaticInst(_mnemonic, _machInst, No_OpClass)
+ {
+ // don't call execute() (which panics) if we're on a
+ // speculative path
+ flags[IsNonSpeculative] = true;
+ }
+
+ %(BasicExecDeclare)s
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+ /**
+ * Base class for unimplemented instructions that cause a warning
+ * to be printed (but do not terminate simulation). This
+ * implementation is a little screwy in that it will print a
+ * warning for each instance of a particular unimplemented machine
+ * instruction, not just for each unimplemented opcode. Should
+ * probably make the 'warned' flag a static member of the derived
+ * class.
+ */
+ class WarnUnimplemented : public PowerStaticInst
+ {
+ private:
+ /// Have we warned on this instruction yet?
+ mutable bool warned;
+
+ public:
+ /// Constructor
+ WarnUnimplemented(const char *_mnemonic, MachInst _machInst)
+ : PowerStaticInst(_mnemonic, _machInst, No_OpClass), warned(false)
+ {
+ // don't call execute() (which panics) if we're on a
+ // speculative path
+ flags[IsNonSpeculative] = true;
+ }
+
+ %(BasicExecDeclare)s
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+}};
+
+output decoder {{
+ std::string
+ FailUnimplemented::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ return csprintf("%-10s (unimplemented)", mnemonic);
+ }
+
+ std::string
+ WarnUnimplemented::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ return csprintf("%-10s (unimplemented)", mnemonic);
+ }
+}};
+
+output exec {{
+ Fault
+ FailUnimplemented::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ panic("attempt to execute unimplemented instruction '%s' "
+ "(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
+ inst2string(machInst));
+ return new UnimplementedOpcodeFault;
+ }
+
+ Fault
+ WarnUnimplemented::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ if (!warned) {
+ warn("\tinstruction '%s' unimplemented\n", mnemonic);
+ warned = true;
+ }
+
+ return NoFault;
+ }
+}};
+
+
+def format FailUnimpl() {{
+ iop = InstObjParams(name, 'FailUnimplemented')
+ decode_block = BasicDecodeWithMnemonic.subst(iop)
+}};
+
+def format WarnUnimpl() {{
+ iop = InstObjParams(name, 'WarnUnimplemented')
+ decode_block = BasicDecodeWithMnemonic.subst(iop)
+}};
+
diff --git a/src/arch/power/isa/formats/unknown.isa b/src/arch/power/isa/formats/unknown.isa
new file mode 100644
index 000000000..06e6ece26
--- /dev/null
+++ b/src/arch/power/isa/formats/unknown.isa
@@ -0,0 +1,87 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2007-2008 The Florida State University
+// Copyright (c) 2009 The University of Edinburgh
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Stephen Hines
+// Timothy M. Jones
+
+////////////////////////////////////////////////////////////////////
+//
+// Unknown instructions
+//
+
+output header {{
+ /**
+ * Static instruction class for unknown (illegal) instructions.
+ * These cause simulator termination if they are executed in a
+ * non-speculative mode. This is a leaf class.
+ */
+ class Unknown : public PowerStaticInst
+ {
+ public:
+ /// Constructor
+ Unknown(ExtMachInst _machInst)
+ : PowerStaticInst("unknown", _machInst, No_OpClass)
+ {
+ // don't call execute() (which panics) if we're on a
+ // speculative path
+ flags[IsNonSpeculative] = true;
+ }
+
+ %(BasicExecDeclare)s
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+}};
+
+output decoder {{
+ std::string
+ Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ return csprintf("%-10s (inst 0x%x, opcode 0x%x, binary:%s)",
+ "unknown", machInst, OPCODE, inst2string(machInst));
+ }
+}};
+
+output exec {{
+ Fault
+ Unknown::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ panic("attempt to execute unknown instruction at %#x"
+ "(inst 0x%08x, opcode 0x%x, binary: %s)",
+ xc->readPC(), machInst, OPCODE, inst2string(machInst));
+ return new UnimplementedOpcodeFault;
+ }
+}};
+
+def format Unknown() {{
+ decode_block = 'return new Unknown(machInst);\n'
+}};
+
diff --git a/src/arch/power/isa/formats/util.isa b/src/arch/power/isa/formats/util.isa
new file mode 100644
index 000000000..ab1e530b2
--- /dev/null
+++ b/src/arch/power/isa/formats/util.isa
@@ -0,0 +1,174 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2003-2005 The Regents of The University of Michigan
+// Copyright (c) 2009 The University of Edinburgh
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Steve Reinhardt
+// Korey Sewell
+// Timothy M. Jones
+
+// Some instructions ignore the contents of Ra if Ra == 0,
+// so check for this.
+def template CheckRaDecode {{
+ {
+ if (RA == 0) {
+ return new %(class_name)sRaZero(machInst);
+ } else {
+ return new %(class_name)s(machInst);
+ }
+ }
+}};
+
+
+// Some instructions have extra behaviour if Rc is set.
+def template CheckRcDecode {{
+ {
+ if (RC31 == 0) {
+ return new %(class_name)s(machInst);
+ } else {
+ return new %(class_name)sRcSet(machInst);
+ }
+ }
+}};
+
+
+// Some instructions have extra behaviour if Rc and OE are set.
+def template CheckRcOeDecode {{
+ {
+ if (RC31 == 0) {
+ if (OE == 0) {
+ return new %(class_name)s(machInst);
+ } else {
+ return new %(class_name)sOeSet(machInst);
+ }
+ } else {
+ if (OE == 0) {
+ return new %(class_name)sRcSet(machInst);
+ } else {
+ return new %(class_name)sRcSetOeSet(machInst);
+ }
+ }
+ }
+}};
+
+// Branch instructions always have two versions, one which sets the link
+// register (LR).
+def template CheckLkDecode {{
+ {
+ if (LK == 0) {
+ return new %(class_name)s(machInst);
+ } else {
+ return new %(class_name)sUpdateLr(machInst);
+ }
+ }
+}};
+
+
+let {{
+
+def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ base_class = 'MemOp',
+ decode_template = BasicDecode, exec_template_base = ''):
+ # Make sure flags are in lists (convert to lists if not).
+ mem_flags = makeList(mem_flags)
+ inst_flags = makeList(inst_flags)
+
+ # add hook to get effective addresses into execution trace output.
+ ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
+
+ # Generate InstObjParams for the memory access.
+ iop = InstObjParams(name, Name, base_class,
+ {'ea_code': ea_code,
+ 'memacc_code': memacc_code},
+ inst_flags)
+
+ if mem_flags:
+ s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
+ iop.constructor += s
+
+ fullExecTemplate = eval(exec_template_base + 'Execute')
+ initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
+ completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
+
+ # (header_output, decoder_output, decode_block, exec_output)
+ return (LoadStoreDeclare.subst(iop),
+ LoadStoreConstructor.subst(iop),
+ decode_template.subst(iop),
+ fullExecTemplate.subst(iop)
+ + initiateAccTemplate.subst(iop)
+ + completeAccTemplate.subst(iop))
+
+
+# The generic ALU instruction generator. Integer and fp formats calls this
+# to generate the different output sections.
+def GenAluOp(name, Name, base_class, code, inst_flags, decode_template,
+ constructor_template):
+ iop = InstObjParams(name, Name, base_class,
+ {"code": code},
+ inst_flags)
+ header_output = BasicDeclare.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+
+ # We use constructors dependent on the Rc and OE bits being set
+ decoder_output = constructor_template.subst(iop)
+
+ # The decode block defines which version to use
+ decode_block = decode_template.subst(iop)
+ return (header_output, decoder_output, decode_block, exec_output)
+
+}};
+
+
+output header {{
+ std::string
+ inst2string(MachInst machInst);
+}};
+
+output decoder {{
+
+ std::string
+ inst2string(MachInst machInst)
+ {
+ std::string str = "";
+ uint32_t mask = 0x80000000;
+
+ for(int i=0; i < 32; i++) {
+ if ((machInst & mask) == 0) {
+ str += "0";
+ } else {
+ str += "1";
+ }
+
+ mask = mask >> 1;
+ }
+
+ return str;
+ }
+
+}};
+
+
diff --git a/src/arch/power/isa/includes.isa b/src/arch/power/isa/includes.isa
new file mode 100644
index 000000000..47e8c1411
--- /dev/null
+++ b/src/arch/power/isa/includes.isa
@@ -0,0 +1,92 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2009 The University of Edinburgh
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Timothy M. Jones
+
+////////////////////////////////////////////////////////////////////
+//
+// Output include file directives.
+//
+
+output header {{
+#include <sstream>
+#include <iostream>
+#include <iomanip>
+
+#include "arch/power/insts/branch.hh"
+#include "arch/power/insts/mem.hh"
+#include "arch/power/insts/integer.hh"
+#include "arch/power/insts/floating.hh"
+#include "arch/power/insts/condition.hh"
+#include "arch/power/insts/misc.hh"
+#include "arch/power/insts/static_inst.hh"
+#include "arch/power/isa_traits.hh"
+#include "cpu/static_inst.hh"
+#include "mem/packet.hh"
+
+using namespace PowerISA;
+}};
+
+output decoder {{
+#include <cmath>
+#if defined(linux)
+#include <fenv.h>
+#endif
+
+#include "arch/power/faults.hh"
+#include "arch/power/isa_traits.hh"
+#include "arch/power/utility.hh"
+#include "base/cprintf.hh"
+#include "base/loader/symtab.hh"
+#include "cpu/thread_context.hh"
+
+using namespace PowerISA;
+using std::isnan;
+}};
+
+output exec {{
+#include "arch/power/faults.hh"
+#include "arch/power/isa_traits.hh"
+#include "arch/power/utility.hh"
+
+#include <cmath>
+#if defined(linux)
+#include <fenv.h>
+#endif
+
+#include "base/condcodes.hh"
+#include "cpu/base.hh"
+#include "cpu/exetrace.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
+#include "sim/sim_exit.hh"
+
+using namespace PowerISA;
+using std::isnan;
+}};
+
diff --git a/src/arch/power/isa/main.isa b/src/arch/power/isa/main.isa
new file mode 100644
index 000000000..cce7e39ee
--- /dev/null
+++ b/src/arch/power/isa/main.isa
@@ -0,0 +1,57 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2009 The University of Edinburgh
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Timothy M. Jones
+
+////////////////////////////////////////////////////////////////////
+//
+// Power ISA description file.
+//
+////////////////////////////////////////////////////////////////////
+
+//Include the C++ include directives
+##include "includes.isa"
+
+////////////////////////////////////////////////////////////////////
+//
+// Namespace statement. Everything below this line will be in the
+// PowerISAInst namespace.
+//
+namespace PowerISA;
+
+//Include the bitfield definitions
+##include "bitfields.isa"
+
+//Include the operand_types and operand definitions
+##include "operands.isa"
+
+//Include the definitions for the instruction formats
+##include "formats/formats.isa"
+
+//Include the decoder definition
+##include "decoder.isa"
diff --git a/src/arch/power/isa/operands.isa b/src/arch/power/isa/operands.isa
new file mode 100644
index 000000000..fc6c32685
--- /dev/null
+++ b/src/arch/power/isa/operands.isa
@@ -0,0 +1,81 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2009 The University of Edinburgh
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Timothy M. Jones
+
+def operand_types {{
+ 'sb' : ('signed int', 8),
+ 'ub' : ('unsigned int', 8),
+ 'sh' : ('signed int', 16),
+ 'uh' : ('unsigned int', 16),
+ 'sw' : ('signed int', 32),
+ 'uw' : ('unsigned int', 32),
+ 'sq' : ('signed int', 64),
+ 'uq' : ('unsigned int', 64),
+ 'sf' : ('float', 32),
+ 'df' : ('float', 64)
+}};
+
+def operands {{
+ # General Purpose Integer Reg Operands
+ 'Ra': ('IntReg', 'uw', 'RA', 'IsInteger', 1),
+ 'Rb': ('IntReg', 'uw', 'RB', 'IsInteger', 2),
+ 'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 3),
+ 'Rt': ('IntReg', 'uw', 'RT', 'IsInteger', 4),
+
+ # General Purpose Floating Point Reg Operands
+ 'Fa': ('FloatReg', 'df', 'FRA', 'IsFloating', 1),
+ 'Fb': ('FloatReg', 'df', 'FRB', 'IsFloating', 2),
+ 'Fc': ('FloatReg', 'df', 'FRC', 'IsFloating', 3),
+ 'Fs': ('FloatReg', 'df', 'FRS', 'IsFloating', 4),
+ 'Ft': ('FloatReg', 'df', 'FRT', 'IsFloating', 5),
+
+ # Memory Operand
+ 'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 8),
+
+ # Program counter and next
+ 'PC': ('PC', 'uw', None, (None, None, 'IsControl'), 9),
+ 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 9),
+
+ # Control registers
+ 'CR': ('IntReg', 'uw', 'INTREG_CR', 'IsInteger', 9),
+ 'LR': ('IntReg', 'uw', 'INTREG_LR', 'IsInteger', 9),
+ 'CTR': ('IntReg', 'uw', 'INTREG_CTR', 'IsInteger', 9),
+ 'XER': ('IntReg', 'uw', 'INTREG_XER', 'IsInteger', 9),
+
+ # Setting as IntReg so things are stored as an integer, not double
+ 'FPSCR': ('IntReg', 'uw', 'INTREG_FPSCR', 'IsFloating', 9),
+
+ # Registers for linked loads and stores
+ 'Rsv': ('IntReg', 'uw', 'INTREG_RSV', 'IsInteger', 9),
+ 'RsvLen': ('IntReg', 'uw', 'INTREG_RSV_LEN', 'IsInteger', 9),
+ 'RsvAddr': ('IntReg', 'uw', 'INTREG_RSV_ADDR', 'IsInteger', 9),
+
+ # Hack for non-full-system syscall emulation
+ 'R0': ('IntReg', 'uw', '0', None, 1),
+}};
diff --git a/src/arch/isa_specific.hh b/src/arch/power/isa_traits.hh
index de070bbf9..886c2cb0b 100644
--- a/src/arch/isa_specific.hh
+++ b/src/arch/power/isa_traits.hh
@@ -1,5 +1,7 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * Copyright (c) 2009 The University of Edinburgh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,46 +27,49 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * Authors: Gabe Black
+ * Authors: Timothy M. Jones
+ * Gabe Black
+ * Stephen Hines
*/
-#ifndef __ARCH_ISA_SPECIFIC_HH__
-#define __ARCH_ISA_SPECIFIC_HH__
+#ifndef __ARCH_POWER_ISA_TRAITS_HH__
+#define __ARCH_POWER_ISA_TRAITS_HH__
-//This file provides a mechanism for other source code to bring in
-//files from the ISA being compiled in.
+#include "arch/power/types.hh"
+#include "base/types.hh"
-//These are constants so you can selectively compile code based on the isa.
-//To use them, do something like:
-//
-//#if THE_ISA == YOUR_FAVORITE_ISA
-// conditional_code
-//#endif
-//
-//Note that this is how this file sets up the TheISA macro.
+namespace BigEndianGuest {};
-//These macros have numerical values because otherwise the preprocessor
-//would treat them as 0 in comparisons.
-#define ALPHA_ISA 21064
-#define SPARC_ISA 42
-#define MIPS_ISA 34000
-#define X86_ISA 8086
-#define ARM_ISA 6
+class StaticInstPtr;
-//These tell the preprocessor where to find the files of a particular
-//ISA, and set the "TheISA" macro for use elsewhere.
-#if THE_ISA == ALPHA_ISA
- #define TheISA AlphaISA
-#elif THE_ISA == SPARC_ISA
- #define TheISA SparcISA
-#elif THE_ISA == MIPS_ISA
- #define TheISA MipsISA
-#elif THE_ISA == X86_ISA
- #define TheISA X86ISA
-#elif THE_ISA == ARM_ISA
- #define TheISA ArmISA
-#else
- #error "THE_ISA not set"
-#endif
+namespace PowerISA
+{
-#endif
+using namespace BigEndianGuest;
+
+StaticInstPtr decodeInst(ExtMachInst);
+
+// POWER DOES NOT have a delay slot
+#define ISA_HAS_DELAY_SLOT 0
+
+const Addr PageShift = 12;
+const Addr PageBytes = ULL(1) << PageShift;
+const Addr Page_Mask = ~(PageBytes - 1);
+const Addr PageOffset = PageBytes - 1;
+
+const Addr PteShift = 3;
+const Addr NPtePageShift = PageShift - PteShift;
+const Addr NPtePage = ULL(1) << NPtePageShift;
+const Addr PteMask = NPtePage - 1;
+
+const int LogVMPageSize = 12; // 4K bytes
+const int VMPageSize = (1 << LogVMPageSize);
+
+const int MachineBytes = 4;
+
+// This is ori 0, 0, 0
+const ExtMachInst NoopMachInst = 0x60000000;
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_ISA_TRAITS_HH__
diff --git a/src/arch/power/linux/linux.cc b/src/arch/power/linux/linux.cc
new file mode 100644
index 000000000..113f3e48e
--- /dev/null
+++ b/src/arch/power/linux/linux.cc
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * Copyright (c) 2009 The University of Edinburgh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Timothy M. Jones
+ */
+
+#include "arch/power/linux/linux.hh"
+
+#include <fcntl.h>
+
+// open(2) flags translation table
+OpenFlagTransTable PowerLinux::openFlagTable[] = {
+#ifdef _MSC_VER
+ { PowerLinux::TGT_O_RDONLY, _O_RDONLY },
+ { PowerLinux::TGT_O_WRONLY, _O_WRONLY },
+ { PowerLinux::TGT_O_RDWR, _O_RDWR },
+ { PowerLinux::TGT_O_APPEND, _O_APPEND },
+ { PowerLinux::TGT_O_CREAT, _O_CREAT },
+ { PowerLinux::TGT_O_TRUNC, _O_TRUNC },
+ { PowerLinux::TGT_O_EXCL, _O_EXCL },
+#ifdef _O_NONBLOCK
+ { PowerLinux::TGT_O_NONBLOCK, _O_NONBLOCK },
+#endif
+#ifdef _O_NOCTTY
+ { PowerLinux::TGT_O_NOCTTY, _O_NOCTTY },
+#endif
+#ifdef _O_SYNC
+ { PowerLinux::TGT_O_SYNC, _O_SYNC },
+#endif
+#ifdef _O_LARGEFILE
+ { PowerLinux::TGT_O_LARGEFILE, _O_LARGEFILE },
+#endif
+#else /* !_MSC_VER */
+ { PowerLinux::TGT_O_RDONLY, O_RDONLY },
+ { PowerLinux::TGT_O_WRONLY, O_WRONLY },
+ { PowerLinux::TGT_O_RDWR, O_RDWR },
+ { PowerLinux::TGT_O_APPEND, O_APPEND },
+ { PowerLinux::TGT_O_CREAT, O_CREAT },
+ { PowerLinux::TGT_O_TRUNC, O_TRUNC },
+ { PowerLinux::TGT_O_EXCL, O_EXCL },
+ { PowerLinux::TGT_O_NONBLOCK, O_NONBLOCK },
+ { PowerLinux::TGT_O_NOCTTY, O_NOCTTY },
+#ifdef O_SYNC
+ { PowerLinux::TGT_O_SYNC, O_SYNC },
+#endif
+#ifdef O_LARGEFILE
+ { PowerLinux::TGT_O_LARGEFILE, O_LARGEFILE },
+#endif
+#endif /* _MSC_VER */
+};
+
+const int PowerLinux::NUM_OPEN_FLAGS =
+ (sizeof(PowerLinux::openFlagTable)/sizeof(PowerLinux::openFlagTable[0]));
+
diff --git a/src/arch/power/linux/linux.hh b/src/arch/power/linux/linux.hh
new file mode 100644
index 000000000..c681c8baf
--- /dev/null
+++ b/src/arch/power/linux/linux.hh
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * Copyright (c) 2009 The University of Edinburgh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Timothy M. Jones
+ */
+
+#ifndef __ARCH_POWER_LINUX_LINUX_HH__
+#define __ARCH_POWER_LINUX_LINUX_HH__
+
+#include "kern/linux/linux.hh"
+
+/*
+ * This works for a 2.6.15 kernel.
+ */
+
+class PowerLinux : public Linux
+{
+ public:
+
+ typedef int32_t time_t;
+
+ typedef struct {
+ uint64_t st_dev;
+ uint32_t __pad1;
+ uint32_t st_ino;
+ uint32_t st_mode;
+ uint32_t st_nlink;
+ uint32_t st_uid;
+ uint32_t st_gid;
+ uint64_t st_rdev;
+ uint32_t __pad2;
+ uint32_t st_size;
+ uint32_t st_blksize;
+ uint32_t st_blocks;
+ uint32_t st_atimeX;
+ uint32_t st_atime_nsec;
+ uint32_t st_mtimeX;
+ uint32_t st_mtime_nsec;
+ uint32_t st_ctimeX;
+ uint32_t st_ctime_nsec;
+ uint32_t __unused4;
+ uint32_t __unused5;
+ } tgt_stat;
+
+ typedef struct {
+ uint64_t st_dev;
+ uint64_t st_ino;
+ uint32_t st_mode;
+ uint32_t st_nlink;
+ uint32_t st_uid;
+ uint32_t st_gid;
+ uint64_t st_rdev;
+ uint64_t __pad2;
+ uint64_t st_size;
+ uint32_t st_blksize;
+ uint32_t __blksize_pad;
+ uint64_t st_blocks;
+ uint32_t st_atimeX;
+ uint32_t st_atime_nsec;
+ uint32_t st_mtimeX;
+ uint32_t st_mtime_nsec;
+ uint32_t st_ctimeX;
+ uint32_t st_ctime_nsec;
+ uint32_t __unused4;
+ uint32_t __unused5;
+ } tgt_stat64;
+
+ /// For times().
+ struct tms {
+ int32_t tms_utime; //!< user time
+ int32_t tms_stime; //!< system time
+ int32_t tms_cutime; //!< user time of children
+ int32_t tms_cstime; //!< system time of children
+ };
+
+ /// This table maps the target open() flags to the corresponding
+ /// host open() flags.
+ static OpenFlagTransTable openFlagTable[];
+
+ /// Number of entries in openFlagTable[].
+ static const int NUM_OPEN_FLAGS;
+
+ //@{
+ /// open(2) flag values.
+ static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY
+ static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY
+ static const int TGT_O_RDWR = 00000002; //!< O_RDWR
+ static const int TGT_O_CREAT = 00000100; //!< O_CREAT
+ static const int TGT_O_EXCL = 00000200; //!< O_EXCL
+ static const int TGT_O_NOCTTY = 00000400; //!< O_NOCTTY
+ static const int TGT_O_TRUNC = 00001000; //!< O_TRUNC
+ static const int TGT_O_APPEND = 00002000; //!< O_APPEND
+ static const int TGT_O_NONBLOCK = 00004000; //!< O_NONBLOCK
+ static const int TGT_O_SYNC = 00010000; //!< O_SYNC
+ static const int TGT_FASYNC = 00020000; //!< FASYNC
+ static const int TGT_O_DIRECTORY = 00040000; //!< O_DIRECTORY
+ static const int TGT_O_NOFOLLOW = 00100000; //!< O_NOFOLLOW
+ static const int TGT_O_LARGEFILE = 00200000; //!< O_LARGEFILE
+ static const int TGT_O_DIRECT = 00400000; //!< O_DIRECT
+ static const int TGT_O_NOATIME = 01000000; //!< O_NOATIME
+ //@}
+
+ /// For mmap().
+ static const unsigned TGT_MAP_ANONYMOUS = 0x800;
+
+ //@{
+ /// ioctl() command codes.
+ /// These are for the 2.6.15 kernel. Some have changed for
+ /// later versions.
+ static const unsigned TIOCGETP_ = 0x40067408;
+ static const unsigned TIOCSETP_ = 0x80067409;
+ static const unsigned TIOCSETN_ = 0x8006740a;
+ static const unsigned TIOCSETC_ = 0x80067411;
+ static const unsigned TIOCGETC_ = 0x40067412;
+ static const unsigned FIONREAD_ = 0x4004667f;
+ static const unsigned TIOCISATTY_ = 0x2000745e;
+ static const unsigned TIOCGETS_ = 0x402c7413;
+ static const unsigned TIOCGETA_ = 0x40147417;
+ static const unsigned TCSETAW_ = 0x80147419;
+ //@}
+};
+
+#endif // __ARCH_POWER_LINUX_LINUX_HH__
diff --git a/src/arch/power/linux/process.cc b/src/arch/power/linux/process.cc
new file mode 100644
index 000000000..504d0e334
--- /dev/null
+++ b/src/arch/power/linux/process.cc
@@ -0,0 +1,456 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * Copyright (c) 2009 The University of Edinburgh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Korey Sewell
+ * Stephen Hines
+ * Timothy M. Jones
+ */
+
+#include "arch/power/linux/linux.hh"
+#include "arch/power/linux/process.hh"
+#include "arch/power/isa_traits.hh"
+
+#include "base/trace.hh"
+#include "cpu/thread_context.hh"
+#include "kern/linux/linux.hh"
+
+#include "sim/process.hh"
+#include "sim/syscall_emul.hh"
+#include "sim/system.hh"
+
+using namespace std;
+using namespace PowerISA;
+
+/// Target uname() handler.
+static SyscallReturn
+unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+ ThreadContext *tc)
+{
+ int index = 0;
+ TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, index));
+
+ strcpy(name->sysname, "Linux");
+ strcpy(name->nodename, "m5.eecs.umich.edu");
+ strcpy(name->release, "2.6.16.19");
+ strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
+ strcpy(name->machine, "power");
+
+ name.copyOut(tc->getMemPort());
+ return 0;
+}
+
+SyscallDesc PowerLinuxProcess::syscallDescs[] = {
+ /* 0 */ SyscallDesc("syscall", unimplementedFunc),
+ /* 1 */ SyscallDesc("exit", exitFunc),
+ /* 2 */ SyscallDesc("fork", unimplementedFunc),
+ /* 3 */ SyscallDesc("read", readFunc),
+ /* 4 */ SyscallDesc("write", writeFunc),
+ /* 5 */ SyscallDesc("open", openFunc<PowerLinux>),
+ /* 6 */ SyscallDesc("close", closeFunc),
+ /* 7 */ SyscallDesc("waitpid", unimplementedFunc), //???
+ /* 8 */ SyscallDesc("creat", unimplementedFunc),
+ /* 9 */ SyscallDesc("link", unimplementedFunc),
+ /* 10 */ SyscallDesc("unlink", unlinkFunc),
+ /* 11 */ SyscallDesc("execve", unimplementedFunc),
+ /* 12 */ SyscallDesc("chdir", unimplementedFunc),
+ /* 13 */ SyscallDesc("time", timeFunc<PowerLinux>),
+ /* 14 */ SyscallDesc("mknod", unimplementedFunc),
+ /* 15 */ SyscallDesc("chmod", chmodFunc<PowerLinux>),
+ /* 16 */ SyscallDesc("lchown", chownFunc),
+ /* 17 */ SyscallDesc("break", brkFunc), //???
+ /* 18 */ SyscallDesc("unused#18", unimplementedFunc), //???
+ /* 19 */ SyscallDesc("lseek", lseekFunc),
+ /* 20 */ SyscallDesc("getpid", getpidFunc),
+ /* 21 */ SyscallDesc("mount", unimplementedFunc),
+ /* 22 */ SyscallDesc("umount", unimplementedFunc),
+ /* 23 */ SyscallDesc("setuid", setuidFunc),
+ /* 24 */ SyscallDesc("getuid", getuidFunc),
+ /* 25 */ SyscallDesc("stime", unimplementedFunc),
+ /* 26 */ SyscallDesc("ptrace", unimplementedFunc),
+ /* 27 */ SyscallDesc("alarm", unimplementedFunc),
+ /* 28 */ SyscallDesc("unused#28", unimplementedFunc),
+ /* 29 */ SyscallDesc("pause", unimplementedFunc),
+ /* 30 */ SyscallDesc("utime", unimplementedFunc),
+ /* 31 */ SyscallDesc("stty", unimplementedFunc),
+ /* 32 */ SyscallDesc("gtty", unimplementedFunc),
+ /* 33 */ SyscallDesc("access", unimplementedFunc),
+ /* 34 */ SyscallDesc("nice", unimplementedFunc),
+ /* 35 */ SyscallDesc("ftime", unimplementedFunc),
+ /* 36 */ SyscallDesc("sync", unimplementedFunc),
+ /* 37 */ SyscallDesc("kill", ignoreFunc),
+ /* 38 */ SyscallDesc("rename", renameFunc),
+ /* 39 */ SyscallDesc("mkdir", unimplementedFunc),
+ /* 40 */ SyscallDesc("rmdir", unimplementedFunc),
+ /* 41 */ SyscallDesc("dup", dupFunc),
+ /* 42 */ SyscallDesc("pipe", unimplementedFunc),
+ /* 43 */ SyscallDesc("times", timesFunc<PowerLinux>),
+ /* 44 */ SyscallDesc("prof", unimplementedFunc),
+ /* 45 */ SyscallDesc("brk", brkFunc),
+ /* 46 */ SyscallDesc("setgid", unimplementedFunc),
+ /* 47 */ SyscallDesc("getgid", getgidFunc),
+ /* 48 */ SyscallDesc("signal", ignoreFunc),
+ /* 49 */ SyscallDesc("geteuid", geteuidFunc),
+ /* 50 */ SyscallDesc("getegid", getegidFunc),
+ /* 51 */ SyscallDesc("acct", unimplementedFunc),
+ /* 52 */ SyscallDesc("umount2", unimplementedFunc),
+ /* 53 */ SyscallDesc("lock", unimplementedFunc),
+ /* 54 */ SyscallDesc("ioctl", ioctlFunc<PowerLinux>),
+ /* 55 */ SyscallDesc("fcntl", fcntlFunc),
+ /* 56 */ SyscallDesc("mpx", unimplementedFunc),
+ /* 57 */ SyscallDesc("setpgid", unimplementedFunc),
+ /* 58 */ SyscallDesc("ulimit", unimplementedFunc),
+ /* 59 */ SyscallDesc("unused#59", unimplementedFunc),
+ /* 60 */ SyscallDesc("umask", umaskFunc),
+ /* 61 */ SyscallDesc("chroot", unimplementedFunc),
+ /* 62 */ SyscallDesc("ustat", unimplementedFunc),
+ /* 63 */ SyscallDesc("dup2", unimplementedFunc),
+ /* 64 */ SyscallDesc("getppid", getpagesizeFunc),
+ /* 65 */ SyscallDesc("getpgrp", unimplementedFunc),
+ /* 66 */ SyscallDesc("setsid", unimplementedFunc),
+ /* 67 */ SyscallDesc("sigaction",unimplementedFunc),
+ /* 68 */ SyscallDesc("sgetmask", unimplementedFunc),
+ /* 69 */ SyscallDesc("ssetmask", unimplementedFunc),
+ /* 70 */ SyscallDesc("setreuid", unimplementedFunc),
+ /* 71 */ SyscallDesc("setregid", unimplementedFunc),
+ /* 72 */ SyscallDesc("sigsuspend", unimplementedFunc),
+ /* 73 */ SyscallDesc("sigpending", unimplementedFunc),
+ /* 74 */ SyscallDesc("sethostname", ignoreFunc),
+ /* 75 */ SyscallDesc("setrlimit", ignoreFunc),
+ /* 76 */ SyscallDesc("getrlimit", unimplementedFunc),
+ /* 77 */ SyscallDesc("getrusage", ignoreFunc),
+ /* 78 */ SyscallDesc("gettimeofday", unimplementedFunc),
+ /* 79 */ SyscallDesc("settimeofday", unimplementedFunc),
+ /* 80 */ SyscallDesc("getgroups", unimplementedFunc),
+ /* 81 */ SyscallDesc("setgroups", unimplementedFunc),
+ /* 82 */ SyscallDesc("reserved#82", unimplementedFunc),
+ /* 83 */ SyscallDesc("symlink", unimplementedFunc),
+ /* 84 */ SyscallDesc("unused#84", unimplementedFunc),
+ /* 85 */ SyscallDesc("readlink", unimplementedFunc),
+ /* 86 */ SyscallDesc("uselib", unimplementedFunc),
+ /* 87 */ SyscallDesc("swapon", gethostnameFunc),
+ /* 88 */ SyscallDesc("reboot", unimplementedFunc),
+ /* 89 */ SyscallDesc("readdir", unimplementedFunc),
+ /* 90 */ SyscallDesc("mmap", mmapFunc<PowerLinux>),
+ /* 91 */ SyscallDesc("munmap",munmapFunc),
+ /* 92 */ SyscallDesc("truncate", truncateFunc),
+ /* 93 */ SyscallDesc("ftruncate", ftruncateFunc),
+ /* 94 */ SyscallDesc("fchmod", unimplementedFunc),
+ /* 95 */ SyscallDesc("fchown", unimplementedFunc),
+ /* 96 */ SyscallDesc("getpriority", unimplementedFunc),
+ /* 97 */ SyscallDesc("setpriority", unimplementedFunc),
+ /* 98 */ SyscallDesc("profil", unimplementedFunc),
+ /* 99 */ SyscallDesc("statfs", unimplementedFunc),
+ /* 100 */ SyscallDesc("fstatfs", unimplementedFunc),
+ /* 101 */ SyscallDesc("ioperm", unimplementedFunc),
+ /* 102 */ SyscallDesc("socketcall", unimplementedFunc),
+ /* 103 */ SyscallDesc("syslog", unimplementedFunc),
+ /* 104 */ SyscallDesc("setitimer", unimplementedFunc),
+ /* 105 */ SyscallDesc("getitimer", unimplementedFunc),
+ /* 106 */ SyscallDesc("stat", statFunc<PowerLinux>),
+ /* 107 */ SyscallDesc("lstat", unimplementedFunc),
+ /* 108 */ SyscallDesc("fstat", fstatFunc<PowerLinux>),
+ /* 109 */ SyscallDesc("unused#109", unimplementedFunc),
+ /* 110 */ SyscallDesc("iopl", unimplementedFunc),
+ /* 111 */ SyscallDesc("vhangup", unimplementedFunc),
+ /* 112 */ SyscallDesc("idle", ignoreFunc),
+ /* 113 */ SyscallDesc("vm86", unimplementedFunc),
+ /* 114 */ SyscallDesc("wait4", unimplementedFunc),
+ /* 115 */ SyscallDesc("swapoff", unimplementedFunc),
+ /* 116 */ SyscallDesc("sysinfo", unimplementedFunc),
+ /* 117 */ SyscallDesc("ipc", unimplementedFunc),
+ /* 118 */ SyscallDesc("fsync", unimplementedFunc),
+ /* 119 */ SyscallDesc("sigreturn", unimplementedFunc),
+ /* 120 */ SyscallDesc("clone", unimplementedFunc),
+ /* 121 */ SyscallDesc("setdomainname", unimplementedFunc),
+ /* 122 */ SyscallDesc("uname", unameFunc),
+ /* 123 */ SyscallDesc("modify_ldt", unimplementedFunc),
+ /* 124 */ SyscallDesc("adjtimex", unimplementedFunc),
+ /* 125 */ SyscallDesc("mprotect", ignoreFunc),
+ /* 126 */ SyscallDesc("sigprocmask", unimplementedFunc),
+ /* 127 */ SyscallDesc("create_module", unimplementedFunc),
+ /* 128 */ SyscallDesc("init_module", unimplementedFunc),
+ /* 129 */ SyscallDesc("delete_module", unimplementedFunc),
+ /* 130 */ SyscallDesc("get_kernel_syms", unimplementedFunc),
+ /* 131 */ SyscallDesc("quotactl", unimplementedFunc),
+ /* 132 */ SyscallDesc("getpgid", unimplementedFunc),
+ /* 133 */ SyscallDesc("fchdir", unimplementedFunc),
+ /* 134 */ SyscallDesc("bdflush", unimplementedFunc),
+ /* 135 */ SyscallDesc("sysfs", unimplementedFunc),
+ /* 136 */ SyscallDesc("personality", unimplementedFunc),
+ /* 137 */ SyscallDesc("afs_syscall", unimplementedFunc),
+ /* 138 */ SyscallDesc("setfsuid", unimplementedFunc),
+ /* 139 */ SyscallDesc("setfsgid", unimplementedFunc),
+ /* 140 */ SyscallDesc("llseek", _llseekFunc),
+ /* 141 */ SyscallDesc("getdents", unimplementedFunc),
+ /* 142 */ SyscallDesc("newselect", unimplementedFunc),
+ /* 143 */ SyscallDesc("flock", unimplementedFunc),
+ /* 144 */ SyscallDesc("msync", unimplementedFunc),
+ /* 145 */ SyscallDesc("readv", unimplementedFunc),
+ /* 146 */ SyscallDesc("writev", writevFunc<PowerLinux>),
+ /* 147 */ SyscallDesc("getsid", unimplementedFunc),
+ /* 148 */ SyscallDesc("fdatasync", unimplementedFunc),
+ /* 149 */ SyscallDesc("sysctl", unimplementedFunc),
+ /* 150 */ SyscallDesc("mlock", unimplementedFunc),
+ /* 151 */ SyscallDesc("munlock", unimplementedFunc),
+ /* 152 */ SyscallDesc("mlockall", unimplementedFunc),
+ /* 153 */ SyscallDesc("munlockall", unimplementedFunc),
+ /* 154 */ SyscallDesc("sched_setparam", unimplementedFunc),
+ /* 155 */ SyscallDesc("sched_getparam", unimplementedFunc),
+ /* 156 */ SyscallDesc("sched_setscheduler", unimplementedFunc),
+ /* 157 */ SyscallDesc("sched_getscheduler", unimplementedFunc),
+ /* 158 */ SyscallDesc("sched_yield", unimplementedFunc),
+ /* 159 */ SyscallDesc("sched_get_priority_max", unimplementedFunc),
+ /* 160 */ SyscallDesc("sched_get_priority_min", unimplementedFunc),
+ /* 161 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc),
+ /* 162 */ SyscallDesc("nanosleep", unimplementedFunc),
+ /* 163 */ SyscallDesc("mremap", unimplementedFunc),
+ /* 164 */ SyscallDesc("setresuid", unimplementedFunc),
+ /* 165 */ SyscallDesc("getresuid", unimplementedFunc),
+ /* 166 */ SyscallDesc("vm862", unimplementedFunc),
+ /* 167 */ SyscallDesc("query_module", unimplementedFunc),
+ /* 168 */ SyscallDesc("poll", unimplementedFunc),
+ /* 169 */ SyscallDesc("nfsservctl", unimplementedFunc),
+ /* 170 */ SyscallDesc("setresgid", unimplementedFunc),
+ /* 171 */ SyscallDesc("getresgid", unimplementedFunc),
+ /* 172 */ SyscallDesc("prctl", unimplementedFunc),
+ /* 173 */ SyscallDesc("rt_sigaction", ignoreFunc),
+ /* 174 */ SyscallDesc("rt_sigprocmask", unimplementedFunc),
+ /* 175 */ SyscallDesc("unknown#175", unimplementedFunc),
+ /* 176 */ SyscallDesc("rt_sigpending", unimplementedFunc),
+ /* 177 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
+ /* 178 */ SyscallDesc("rt_sigqueueinfo", ignoreFunc),
+ /* 179 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
+ /* 180 */ SyscallDesc("pread64", unimplementedFunc),
+ /* 181 */ SyscallDesc("pwrite64", unimplementedFunc),
+ /* 182 */ SyscallDesc("chown", unimplementedFunc),
+ /* 183 */ SyscallDesc("getcwd", unimplementedFunc),
+ /* 184 */ SyscallDesc("capget", unimplementedFunc),
+ /* 185 */ SyscallDesc("capset", unimplementedFunc),
+ /* 186 */ SyscallDesc("sigaltstack", unimplementedFunc),
+ /* 187 */ SyscallDesc("sendfile", unimplementedFunc),
+ /* 188 */ SyscallDesc("getpmsg", unimplementedFunc),
+ /* 189 */ SyscallDesc("putpmsg", unimplementedFunc),
+ /* 190 */ SyscallDesc("ugetrlimit", ignoreFunc),
+ /* 191 */ SyscallDesc("getrlimit", unimplementedFunc),
+ /* 192 */ SyscallDesc("mmap2", mmapFunc<PowerLinux>),
+ /* 193 */ SyscallDesc("truncate64", unimplementedFunc),
+ /* 194 */ SyscallDesc("ftruncate64", ftruncate64Func),
+ /* 195 */ SyscallDesc("stat64", stat64Func<PowerLinux>),
+ /* 196 */ SyscallDesc("lstat64", lstat64Func<PowerLinux>),
+ /* 197 */ SyscallDesc("fstat64", fstat64Func<PowerLinux>),
+ /* 198 */ SyscallDesc("lchown", unimplementedFunc),
+ /* 199 */ SyscallDesc("getuid", getuidFunc),
+ /* 200 */ SyscallDesc("getgid", getgidFunc),
+ /* 201 */ SyscallDesc("geteuid", geteuidFunc),
+ /* 202 */ SyscallDesc("getegid", getegidFunc),
+ /* 203 */ SyscallDesc("setreuid", unimplementedFunc),
+ /* 204 */ SyscallDesc("fcntl64", fcntl64Func),
+ /* 205 */ SyscallDesc("getgroups", unimplementedFunc),
+ /* 206 */ SyscallDesc("setgroups", unimplementedFunc),
+ /* 207 */ SyscallDesc("fchown", unimplementedFunc),
+ /* 208 */ SyscallDesc("setresuid", unimplementedFunc),
+ /* 209 */ SyscallDesc("getresuid", unimplementedFunc),
+ /* 210 */ SyscallDesc("setresgid", unimplementedFunc),
+ /* 211 */ SyscallDesc("getresgid", unimplementedFunc),
+ /* 212 */ SyscallDesc("chown", unimplementedFunc),
+ /* 213 */ SyscallDesc("setuid", unimplementedFunc),
+ /* 214 */ SyscallDesc("setgid", unimplementedFunc),
+ /* 215 */ SyscallDesc("setfsuid", unimplementedFunc),
+ /* 216 */ SyscallDesc("setfsgid", unimplementedFunc),
+ /* 217 */ SyscallDesc("getdents64", unimplementedFunc),
+ /* 218 */ SyscallDesc("pivot_root", unimplementedFunc),
+ /* 219 */ SyscallDesc("mincore", unimplementedFunc),
+ /* 220 */ SyscallDesc("madvise", unimplementedFunc),
+ /* 221 */ SyscallDesc("unknown#221", unimplementedFunc),
+ /* 222 */ SyscallDesc("tux", unimplementedFunc),
+ /* 223 */ SyscallDesc("unknown#223", unimplementedFunc),
+ /* 224 */ SyscallDesc("gettid", unimplementedFunc),
+ /* 225 */ SyscallDesc("readahead", unimplementedFunc),
+ /* 226 */ SyscallDesc("setxattr", unimplementedFunc),
+ /* 227 */ SyscallDesc("lsetxattr", unimplementedFunc),
+ /* 228 */ SyscallDesc("fsetxattr", unimplementedFunc),
+ /* 229 */ SyscallDesc("getxattr", unimplementedFunc),
+ /* 230 */ SyscallDesc("lgetxattr", unimplementedFunc),
+ /* 231 */ SyscallDesc("fgetxattr", unimplementedFunc),
+ /* 232 */ SyscallDesc("listxattr", unimplementedFunc),
+ /* 233 */ SyscallDesc("llistxattr", unimplementedFunc),
+ /* 234 */ SyscallDesc("exit_group", exitGroupFunc),
+ /* 235 */ SyscallDesc("removexattr", unimplementedFunc),
+ /* 236 */ SyscallDesc("lremovexattr", unimplementedFunc),
+ /* 237 */ SyscallDesc("fremovexattr", unimplementedFunc),
+ /* 238 */ SyscallDesc("tkill", unimplementedFunc),
+ /* 239 */ SyscallDesc("sendfile64", unimplementedFunc),
+ /* 240 */ SyscallDesc("futex", unimplementedFunc),
+ /* 241 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
+ /* 242 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
+ /* 243 */ SyscallDesc("io_setup", unimplementedFunc),
+ /* 244 */ SyscallDesc("io_destory", unimplementedFunc),
+ /* 245 */ SyscallDesc("io_getevents", unimplementedFunc),
+ /* 246 */ SyscallDesc("io_submit", unimplementedFunc),
+ /* 247 */ SyscallDesc("io_cancel", unimplementedFunc),
+ /* 248 */ SyscallDesc("unknown#248", unimplementedFunc),
+ /* 249 */ SyscallDesc("lookup_dcookie", unimplementedFunc),
+ /* 250 */ SyscallDesc("epoll_create", unimplementedFunc),
+ /* 251 */ SyscallDesc("epoll_ctl", unimplementedFunc),
+ /* 252 */ SyscallDesc("epoll_wait", unimplementedFunc),
+ /* 253 */ SyscallDesc("remap_file_pages", unimplementedFunc),
+ /* 254 */ SyscallDesc("set_thread_area", unimplementedFunc),
+ /* 255 */ SyscallDesc("get_thread_area", unimplementedFunc),
+ /* 256 */ SyscallDesc("set_tid_address", unimplementedFunc),
+ /* 257 */ SyscallDesc("timer_create", unimplementedFunc),
+ /* 258 */ SyscallDesc("timer_settime", unimplementedFunc),
+ /* 259 */ SyscallDesc("timer_gettime", unimplementedFunc),
+ /* 260 */ SyscallDesc("timer_getoverrun", unimplementedFunc),
+ /* 261 */ SyscallDesc("timer_delete", unimplementedFunc),
+ /* 262 */ SyscallDesc("clock_settime", unimplementedFunc),
+ /* 263 */ SyscallDesc("clock_gettime", unimplementedFunc),
+ /* 264 */ SyscallDesc("clock_getres", unimplementedFunc),
+ /* 265 */ SyscallDesc("clock_nanosleep", unimplementedFunc),
+ /* 266 */ SyscallDesc("statfs64", unimplementedFunc),
+ /* 267 */ SyscallDesc("fstatfs64", unimplementedFunc),
+ /* 268 */ SyscallDesc("tgkill", unimplementedFunc),
+ /* 269 */ SyscallDesc("utimes", unimplementedFunc),
+ /* 270 */ SyscallDesc("arm_fadvise64_64", unimplementedFunc),
+ /* 271 */ SyscallDesc("pciconfig_iobase", unimplementedFunc),
+ /* 272 */ SyscallDesc("pciconfig_read", unimplementedFunc),
+ /* 273 */ SyscallDesc("pciconfig_write", unimplementedFunc),
+ /* 274 */ SyscallDesc("mq_open", unimplementedFunc),
+ /* 275 */ SyscallDesc("mq_unlink", unimplementedFunc),
+ /* 276 */ SyscallDesc("mq_timedsend", unimplementedFunc),
+ /* 277 */ SyscallDesc("mq_timedreceive", unimplementedFunc),
+ /* 278 */ SyscallDesc("mq_notify", unimplementedFunc),
+ /* 279 */ SyscallDesc("mq_getsetattr", unimplementedFunc),
+ /* 280 */ SyscallDesc("waitid", unimplementedFunc),
+ /* 281 */ SyscallDesc("socket", unimplementedFunc),
+ /* 282 */ SyscallDesc("bind", unimplementedFunc),
+ /* 283 */ SyscallDesc("connect", unimplementedFunc),
+ /* 284 */ SyscallDesc("listen", unimplementedFunc),
+ /* 285 */ SyscallDesc("accept", unimplementedFunc),
+ /* 286 */ SyscallDesc("getsockname", unimplementedFunc),
+ /* 287 */ SyscallDesc("getpeername", unimplementedFunc),
+ /* 288 */ SyscallDesc("socketpair", unimplementedFunc),
+ /* 289 */ SyscallDesc("send", unimplementedFunc),
+ /* 290 */ SyscallDesc("sendto", unimplementedFunc),
+ /* 291 */ SyscallDesc("recv", unimplementedFunc),
+ /* 292 */ SyscallDesc("recvfrom", unimplementedFunc),
+ /* 293 */ SyscallDesc("shutdown", unimplementedFunc),
+ /* 294 */ SyscallDesc("setsockopt", unimplementedFunc),
+ /* 295 */ SyscallDesc("getsockopt", unimplementedFunc),
+ /* 296 */ SyscallDesc("sendmsg", unimplementedFunc),
+ /* 297 */ SyscallDesc("rcvmsg", unimplementedFunc),
+ /* 298 */ SyscallDesc("semop", unimplementedFunc),
+ /* 299 */ SyscallDesc("semget", unimplementedFunc),
+ /* 300 */ SyscallDesc("semctl", unimplementedFunc),
+ /* 301 */ SyscallDesc("msgsend", unimplementedFunc),
+ /* 302 */ SyscallDesc("msgrcv", unimplementedFunc),
+ /* 303 */ SyscallDesc("msgget", unimplementedFunc),
+ /* 304 */ SyscallDesc("msgctl", unimplementedFunc),
+ /* 305 */ SyscallDesc("shmat", unimplementedFunc),
+ /* 306 */ SyscallDesc("shmdt", unimplementedFunc),
+ /* 307 */ SyscallDesc("shmget", unimplementedFunc),
+ /* 308 */ SyscallDesc("shmctl", unimplementedFunc),
+ /* 309 */ SyscallDesc("add_key", unimplementedFunc),
+ /* 310 */ SyscallDesc("request_key", unimplementedFunc),
+ /* 311 */ SyscallDesc("keyctl", unimplementedFunc),
+ /* 312 */ SyscallDesc("semtimedop", unimplementedFunc),
+ /* 313 */ SyscallDesc("vserver", unimplementedFunc),
+ /* 314 */ SyscallDesc("ioprio_set", unimplementedFunc),
+ /* 315 */ SyscallDesc("ioprio_get", unimplementedFunc),
+ /* 316 */ SyscallDesc("inotify_init", unimplementedFunc),
+ /* 317 */ SyscallDesc("inotify_add_watch", unimplementedFunc),
+ /* 318 */ SyscallDesc("inotify_rm_watch", unimplementedFunc),
+ /* 319 */ SyscallDesc("mbind", unimplementedFunc),
+ /* 320 */ SyscallDesc("get_mempolicy", unimplementedFunc),
+ /* 321 */ SyscallDesc("set_mempolicy", unimplementedFunc),
+ /* 322 */ SyscallDesc("openat", unimplementedFunc),
+ /* 323 */ SyscallDesc("mkdirat", unimplementedFunc),
+ /* 324 */ SyscallDesc("mknodat", unimplementedFunc),
+ /* 325 */ SyscallDesc("fchownat", unimplementedFunc),
+ /* 326 */ SyscallDesc("futimesat", unimplementedFunc),
+ /* 327 */ SyscallDesc("fstatat64", unimplementedFunc),
+ /* 328 */ SyscallDesc("unlinkat", unimplementedFunc),
+ /* 329 */ SyscallDesc("renameat", unimplementedFunc),
+ /* 330 */ SyscallDesc("linkat", unimplementedFunc),
+ /* 331 */ SyscallDesc("symlinkat", unimplementedFunc),
+ /* 332 */ SyscallDesc("readlinkat", unimplementedFunc),
+ /* 333 */ SyscallDesc("fchmodat", unimplementedFunc),
+ /* 334 */ SyscallDesc("faccessat", unimplementedFunc),
+ /* 335 */ SyscallDesc("pselect6", unimplementedFunc),
+ /* 336 */ SyscallDesc("ppoll", unimplementedFunc),
+ /* 337 */ SyscallDesc("unshare", unimplementedFunc),
+ /* 338 */ SyscallDesc("set_robust_list", unimplementedFunc),
+ /* 339 */ SyscallDesc("get_robust_list", unimplementedFunc),
+ /* 340 */ SyscallDesc("splice", unimplementedFunc),
+ /* 341 */ SyscallDesc("arm_sync_file_range", unimplementedFunc),
+ /* 342 */ SyscallDesc("tee", unimplementedFunc),
+ /* 343 */ SyscallDesc("vmsplice", unimplementedFunc),
+ /* 344 */ SyscallDesc("move_pages", unimplementedFunc),
+ /* 345 */ SyscallDesc("getcpu", unimplementedFunc),
+ /* 346 */ SyscallDesc("epoll_pwait", unimplementedFunc),
+};
+
+PowerLinuxProcess::PowerLinuxProcess(LiveProcessParams * params,
+ ObjectFile *objFile)
+ : PowerLiveProcess(params, objFile),
+ Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
+{
+}
+
+SyscallDesc*
+PowerLinuxProcess::getDesc(int callnum)
+{
+ if (callnum < 0 || callnum > Num_Syscall_Descs)
+ return NULL;
+
+ return &syscallDescs[callnum];
+}
+
+void
+PowerLinuxProcess::startup()
+{
+ PowerLiveProcess::startup();
+}
+
+PowerISA::IntReg
+PowerLinuxProcess::getSyscallArg(ThreadContext *tc, int &i)
+{
+ // Linux apparently allows more parameter than the ABI says it should.
+ // This limit may need to be increased even further.
+ assert(i < 6);
+ return tc->readIntReg(ArgumentReg0 + i++);
+}
+
+void
+PowerLinuxProcess::setSyscallArg(ThreadContext *tc, int i, PowerISA::IntReg val)
+{
+ // Linux apparently allows more parameter than the ABI says it should.
+ // This limit may need to be increased even further.
+ assert(i < 6);
+ tc->setIntReg(ArgumentReg0 + i, val);
+}
diff --git a/src/mem/slicc/generator/fileio.cc b/src/arch/power/linux/process.hh
index 15eccd3ca..db6759a77 100644
--- a/src/mem/slicc/generator/fileio.cc
+++ b/src/arch/power/linux/process.hh
@@ -1,6 +1,6 @@
-
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2007-2008 The Florida State University
+ * Copyright (c) 2009 The University of Edinburgh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,42 +25,34 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Stephen Hines
+ * Timothy M. Jones
*/
-/*
- * fileio.C
- *
- * Description: See fileio.hh
- *
- * $Id: fileio.C,v 3.3 2003/07/10 18:08:08 milo Exp $
- *
- * */
+#ifndef __POWER_LINUX_PROCESS_HH__
+#define __POWER_LINUX_PROCESS_HH__
+
+#include "arch/power/process.hh"
-#include "mem/slicc/generator/fileio.hh"
-void conditionally_write_file(string filename, ostringstream& sstr)
+/// A process with emulated PPC/Linux syscalls.
+class PowerLinuxProcess : public PowerLiveProcess
{
- ofstream out;
- ifstream in;
- string input_file;
+ public:
+ PowerLinuxProcess(LiveProcessParams * params, ObjectFile *objFile);
+
+ virtual SyscallDesc* getDesc(int callnum);
+
+ void startup();
+
+ PowerISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
+ void setSyscallArg(ThreadContext *tc, int i, PowerISA::IntReg val);
- // Read in the file if it exists
- in.open(filename.c_str());
- char c;
- while (in.get(c)) {
- input_file += c;
- }
- in.close();
+ /// Array of syscall descriptors, indexed by call number.
+ static SyscallDesc syscallDescs[];
- // Check to see if the file is the same as what we want to write
- if (input_file != sstr.str()) {
- cout << " Overwriting file: " << filename << endl;
- // Overwrite the old file with the new file
- out.open(filename.c_str());
- out << sstr.str();
- out.close();
- } else {
- //cout << " Keeping old file: " << filename << endl;
- }
-}
+ const int Num_Syscall_Descs;
+};
+#endif // __POWER_LINUX_PROCESS_HH__
diff --git a/src/mem/slicc/ast/PairAST.cc b/src/arch/power/locked_mem.hh
index c42843cce..56ab1d4a0 100644
--- a/src/mem/slicc/ast/PairAST.cc
+++ b/src/arch/power/locked_mem.hh
@@ -1,6 +1,7 @@
-
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * Copyright (c) 2009 The University of Edinburgh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,48 +26,39 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Steve Reinhardt
+ * Stephen Hines
+ * Timothy M. Jones
*/
-/*
- * PairAST.C
- *
- * Description: See PairAST.hh
- *
- * $Id$
+#ifndef __ARCH_POWER_LOCKED_MEM_HH__
+#define __ARCH_POWER_LOCKED_MEM_HH__
+
+/**
+ * @file
*
+ * ISA-specific helper functions for locked memory accesses.
*/
-#include "mem/slicc/ast/PairAST.hh"
+#include "mem/request.hh"
-PairAST::PairAST(string* key_ptr, string* value_ptr)
- : AST()
+namespace PowerISA
{
- m_key_ptr = key_ptr;
- m_value_ptr = value_ptr;
-}
-
-PairAST::PairAST(string key, string* value_ptr)
- : AST()
-{
- m_key_ptr = new string(key);
- m_value_ptr = value_ptr;
-}
-PairAST::PairAST(string key, string value)
- : AST()
+template <class XC>
+inline void
+handleLockedRead(XC *xc, Request *req)
{
- m_key_ptr = new string(key);
- m_value_ptr = new string(value);
}
-PairAST::~PairAST()
+template <class XC>
+inline bool
+handleLockedWrite(XC *xc, Request *req)
{
- delete m_key_ptr;
- delete m_value_ptr;
+ return true;
}
-void PairAST::print(ostream& out) const
-{
- out << "[" << *m_key_ptr << "=" << *m_value_ptr << "]" << endl;
-}
+} // PowerISA namespace
+#endif // __ARCH_POWER_LOCKED_MEM_HH__
diff --git a/src/mem/slicc/ast/PairListAST.cc b/src/arch/power/microcode_rom.hh
index 76892d437..e35db5112 100644
--- a/src/mem/slicc/ast/PairListAST.cc
+++ b/src/arch/power/microcode_rom.hh
@@ -1,6 +1,6 @@
-
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 The Regents of The University of Michigan
+ * Copyright (c) 2009 The University of Edinburgh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,25 +25,21 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * PairListAST.C
- *
- * Description: See PairListAST.hh
- *
- * $Id$
*
+ * Authors: Gabe Black
+ * Timothy M. Jones
*/
-#include "mem/slicc/ast/PairListAST.hh"
+#ifndef __ARCH_POWER_MICROCODE_ROM_HH__
+#define __ARCH_POWER_MICROCODE_ROM_HH__
-void PairListAST::addPair(PairAST* pair_ptr)
-{
- getPairs().add(pair_ptr->key(), pair_ptr->value());
-}
+#include "sim/microcode_rom.hh"
-void PairListAST::print(ostream& out) const
+namespace PowerISA
{
- out << "[PairListAST] " << getPairs();
-}
+
+using ::MicrocodeRom;
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_MICROCODE_ROM_HH__
diff --git a/src/mem/slicc/ast/CheckAllocateStatementAST.hh b/src/arch/power/miscregs.hh
index 1df853514..cd9815b2a 100644
--- a/src/mem/slicc/ast/CheckAllocateStatementAST.hh
+++ b/src/arch/power/miscregs.hh
@@ -1,6 +1,5 @@
-
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009 The University of Edinburgh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,58 +24,72 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
*
+ * Authors: Timothy M. Jones
*/
-#ifndef CHECKALLOCATESTATEMENTAST_H
-#define CHECKALLOCATESTATEMENTAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/StatementAST.hh"
-#include "mem/slicc/ast/TypeAST.hh"
-
-class VarExprAST;
-class Var;
+#ifndef __ARCH_POWER_MISCREGS_HH__
+#define __ARCH_POWER_MISCREGS_HH__
-class CheckAllocateStatementAST : public StatementAST {
-public:
- // Constructors
- CheckAllocateStatementAST(VarExprAST* variable);
+#include "base/bitunion.hh"
- // Destructor
- ~CheckAllocateStatementAST();
-
- // Public Methods
- void generate(string& code, Type* return_type_ptr) const;
- void findResources(Map<Var*, string>& resource_list) const;
- void print(ostream& out) const;
-private:
- // Private Methods
+namespace PowerISA
+{
- // Private copy constructor and assignment operator
- CheckAllocateStatementAST(const CheckAllocateStatementAST& obj);
- CheckAllocateStatementAST& operator=(const CheckAllocateStatementAST& obj);
+enum MiscRegIndex {
+ NUM_MISCREGS = 0
+};
- // Data Members (m_ prefix)
- VarExprAST* m_variable;
+const char * const miscRegName[NUM_MISCREGS] = {
};
-// Output operator declaration
-ostream& operator<<(ostream& out, const CheckAllocateStatementAST& obj);
+BitUnion32(Cr)
+ Bitfield<31,28> cr0;
+ Bitfield<27,24> cr1;
+EndBitUnion(Cr)
-// ******************* Definitions *******************
+BitUnion32(Xer)
+ Bitfield<31> so;
+ Bitfield<30> ov;
+ Bitfield<29> ca;
+EndBitUnion(Xer)
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const CheckAllocateStatementAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
+BitUnion32(Fpscr)
+ Bitfield<31> fx;
+ Bitfield<30> fex;
+ Bitfield<29> vx;
+ Bitfield<28> ox;
+ Bitfield<27> ux;
+ Bitfield<26> zx;
+ Bitfield<25> xx;
+ Bitfield<24> vxsnan;
+ Bitfield<23> vxisi;
+ Bitfield<22> vxidi;
+ Bitfield<21> vxzdz;
+ Bitfield<20> vximz;
+ Bitfield<19> vxvc;
+ Bitfield<18> fr;
+ Bitfield<17> fi;
+ SubBitUnion(fprf, 16, 12)
+ Bitfield<16> c;
+ SubBitUnion(fpcc, 15, 12)
+ Bitfield<15> fl;
+ Bitfield<14> fg;
+ Bitfield<13> fe;
+ Bitfield<12> fu;
+ EndSubBitUnion(fpcc)
+ EndSubBitUnion(fprf)
+ Bitfield<10> vxsqrt;
+ Bitfield<9> vxcvi;
+ Bitfield<8> ve;
+ Bitfield<7> oe;
+ Bitfield<6> ue;
+ Bitfield<5> ze;
+ Bitfield<4> xe;
+ Bitfield<3> ni;
+ Bitfield<2,1> rn;
+EndBitUnion(Fpscr)
+
+}; // PowerISA namespace
-#endif //CHECKALLOCATESTATEMENTAST_H
+#endif // __ARCH_POWER_MISCREGS_HH__
diff --git a/src/arch/power/mmaped_ipr.hh b/src/arch/power/mmaped_ipr.hh
new file mode 100644
index 000000000..bd1ea10b3
--- /dev/null
+++ b/src/arch/power/mmaped_ipr.hh
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * Copyright (c) 2009 The University of Edinburgh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ali Saidi
+ * Stephen Hines
+ * Timothy M. Jones
+ */
+
+#ifndef __ARCH_POWER_MMAPED_IPR_HH__
+#define __ARCH_POWER_MMAPED_IPR_HH__
+
+/**
+ * @file
+ *
+ * ISA-specific helper functions for memory mapped IPR accesses.
+ */
+
+#include "base/misc.hh"
+#include "mem/packet.hh"
+
+class ThreadContext;
+
+namespace PowerISA
+{
+
+inline Tick
+handleIprRead(ThreadContext *xc, Packet *pkt)
+{
+ panic("No implementation for handleIprRead in POWER\n");
+}
+
+inline Tick
+handleIprWrite(ThreadContext *xc, Packet *pkt)
+{
+ panic("No implementation for handleIprWrite in POWER\n");
+}
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_MMAPED_IPR_HH__
diff --git a/src/mem/slicc/ast/EnumExprAST.cc b/src/arch/power/pagetable.cc
index 0d8af0e9f..862404578 100644
--- a/src/mem/slicc/ast/EnumExprAST.cc
+++ b/src/arch/power/pagetable.cc
@@ -1,6 +1,8 @@
-
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007 MIPS Technologies, Inc.
+ * Copyright (c) 2007-2008 The Florida State University
+ * Copyright (c) 2009 The University of Edinburgh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,52 +27,56 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * EnumExprAST.C
- *
- * Description: See EnumExprAST.hh
- *
- * $Id: EnumExprAST.C,v 3.1 2003/07/10 18:08:06 milo Exp $
*
+ * Authors: Nathan Binkert
+ * Steve Reinhardt
+ * Jaidev Patwardhan
+ * Stephen Hines
+ * Timothy M. Jones
*/
-#include "mem/slicc/ast/EnumExprAST.hh"
+#include "arch/power/pagetable.hh"
+#include "sim/serialize.hh"
-EnumExprAST::EnumExprAST(TypeAST* type_ast_ptr,
- string* value_ptr)
- : ExprAST()
+namespace PowerISA
{
- assert(value_ptr != NULL);
- assert(type_ast_ptr != NULL);
- m_type_ast_ptr = type_ast_ptr;
- m_value_ptr = value_ptr;
-}
-EnumExprAST::~EnumExprAST()
+void
+PTE::serialize(std::ostream &os)
{
- delete m_type_ast_ptr;
- delete m_value_ptr;
+ SERIALIZE_SCALAR(Mask);
+ SERIALIZE_SCALAR(VPN);
+ SERIALIZE_SCALAR(asid);
+ SERIALIZE_SCALAR(G);
+ SERIALIZE_SCALAR(PFN0);
+ SERIALIZE_SCALAR(D0);
+ SERIALIZE_SCALAR(V0);
+ SERIALIZE_SCALAR(C0);
+ SERIALIZE_SCALAR(PFN1);
+ SERIALIZE_SCALAR(D1);
+ SERIALIZE_SCALAR(V1);
+ SERIALIZE_SCALAR(C1);
+ SERIALIZE_SCALAR(AddrShiftAmount);
+ SERIALIZE_SCALAR(OffsetMask);
}
-Type* EnumExprAST::generate(string& code) const
+void
+PTE::unserialize(Checkpoint *cp, const std::string &section)
{
- Type* type_ptr = m_type_ast_ptr->lookupType();
- code += type_ptr->cIdent() + "_" + (*m_value_ptr);
-
- // Make sure the enumeration value exists
- if (!type_ptr->enumExist(*m_value_ptr)) {
- error("Type '" + m_type_ast_ptr->toString() + "' does not have enumeration '" + *m_value_ptr + "'");
- }
-
- // Return the proper type
- return type_ptr;
+ UNSERIALIZE_SCALAR(Mask);
+ UNSERIALIZE_SCALAR(VPN);
+ UNSERIALIZE_SCALAR(asid);
+ UNSERIALIZE_SCALAR(G);
+ UNSERIALIZE_SCALAR(PFN0);
+ UNSERIALIZE_SCALAR(D0);
+ UNSERIALIZE_SCALAR(V0);
+ UNSERIALIZE_SCALAR(C0);
+ UNSERIALIZE_SCALAR(PFN1);
+ UNSERIALIZE_SCALAR(D1);
+ UNSERIALIZE_SCALAR(V1);
+ UNSERIALIZE_SCALAR(C1);
+ UNSERIALIZE_SCALAR(AddrShiftAmount);
+ UNSERIALIZE_SCALAR(OffsetMask);
}
-void EnumExprAST::print(ostream& out) const
-{
- string str;
- str += m_type_ast_ptr->toString()+":"+(*m_value_ptr);
- out << "[EnumExpr: " << str << "]";
-}
+} // PowerISA namespace
diff --git a/src/arch/power/pagetable.hh b/src/arch/power/pagetable.hh
new file mode 100644
index 000000000..bd2b9d397
--- /dev/null
+++ b/src/arch/power/pagetable.hh
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007 MIPS Technologies, Inc.
+ * Copyright (c) 2007-2008 The Florida State University
+ * Copyright (c) 2009 The University of Edinburgh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
+ * Steve Reinhardt
+ * Jaidev Patwardhan
+ * Stephen Hines
+ * Timothy M. Jones
+ */
+
+#ifndef __ARCH_POWER_PAGETABLE_H__
+#define __ARCH_POWER_PAGETABLE_H__
+
+#include "arch/power/isa_traits.hh"
+#include "arch/power/utility.hh"
+#include "arch/power/vtophys.hh"
+#include "config/full_system.hh"
+
+namespace PowerISA {
+
+struct VAddr
+{
+ static const int ImplBits = 43;
+ static const Addr ImplMask = (ULL(1) << ImplBits) - 1;
+ static const Addr UnImplMask = ~ImplMask;
+
+ Addr addr;
+
+ VAddr(Addr a)
+ : addr(a)
+ {}
+
+ operator Addr() const
+ {
+ return addr;
+ }
+
+ const VAddr
+ &operator=(Addr a)
+ {
+ addr = a;
+ return *this;
+ }
+
+ Addr
+ vpn() const
+ {
+ return (addr & ImplMask) >> PageShift;
+ }
+
+ Addr
+ page() const
+ {
+ return addr & Page_Mask;
+ }
+
+ Addr
+ offset() const
+ {
+ return addr & PageOffset;
+ }
+
+ Addr
+ level3() const
+ {
+ return PowerISA::PteAddr(addr >> PageShift);
+ }
+
+ Addr
+ level2() const
+ {
+ return PowerISA::PteAddr(addr >> (NPtePageShift + PageShift));
+ }
+
+ Addr
+ level1() const
+ {
+ return PowerISA::PteAddr(addr >> (2 * NPtePageShift + PageShift));
+ }
+};
+
+// ITB/DTB page table entry
+struct PTE
+{
+ // What parts of the VAddr (from bits 28..11) should be used in
+ // translation (includes Mask and MaskX from PageMask)
+ Addr Mask;
+
+ // Virtual Page Number (/2) (Includes VPN2 + VPN2X .. bits 31..11
+ // from EntryHi)
+ Addr VPN;
+
+ // Address Space ID (8 bits) // Lower 8 bits of EntryHi
+ uint8_t asid;
+
+ // Global Bit - Obtained by an *AND* of EntryLo0 and EntryLo1 G bit
+ bool G;
+
+ /* Contents of Entry Lo0 */
+ Addr PFN0; // Physical Frame Number - Even
+ bool D0; // Even entry Dirty Bit
+ bool V0; // Even entry Valid Bit
+ uint8_t C0; // Cache Coherency Bits - Even
+
+ /* Contents of Entry Lo1 */
+ Addr PFN1; // Physical Frame Number - Odd
+ bool D1; // Odd entry Dirty Bit
+ bool V1; // Odd entry Valid Bit
+ uint8_t C1; // Cache Coherency Bits (3 bits)
+
+ // The next few variables are put in as optimizations to reduce TLB
+ // lookup overheads. For a given Mask, what is the address shift amount
+ // and what is the OffsetMask
+ int AddrShiftAmount;
+ int OffsetMask;
+
+ bool
+ Valid()
+ {
+ return (V0 | V1);
+ };
+
+ void serialize(std::ostream &os);
+
+ void unserialize(Checkpoint *cp, const std::string &section);
+};
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_PAGETABLE_H__
+
diff --git a/src/arch/power/predecoder.hh b/src/arch/power/predecoder.hh
new file mode 100644
index 000000000..1f3ac41cb
--- /dev/null
+++ b/src/arch/power/predecoder.hh
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * Copyright (c) 2009 The University of Edinburgh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ * Stephen Hines
+ * Timothy M. Jones
+ */
+
+#ifndef __ARCH_ARM_PREDECODER_HH__
+#define __ARCH_ARM_PREDECODER_HH__
+
+#include "arch/power/types.hh"
+#include "base/misc.hh"
+#include "base/types.hh"
+
+class ThreadContext;
+
+namespace PowerISA
+{
+
+class Predecoder
+{
+ protected:
+ ThreadContext * tc;
+
+ // The extended machine instruction being generated
+ ExtMachInst emi;
+
+ public:
+ Predecoder(ThreadContext * _tc)
+ : tc(_tc)
+ {
+ }
+
+ ThreadContext *
+ getTC()
+ {
+ return tc;
+ }
+
+ void
+ setTC(ThreadContext * _tc)
+ {
+ tc = _tc;
+ }
+
+ void
+ process()
+ {
+ }
+
+ void
+ reset()
+ {
+ }
+
+ // Use this to give data to the predecoder. This should be used
+ // when there is control flow.
+ void
+ moreBytes(Addr pc, Addr fetchPC, MachInst inst)
+ {
+ emi = inst;
+ }
+
+ // Use this to give data to the predecoder. This should be used
+ // when instructions are executed in order.
+ void
+ moreBytes(MachInst machInst)
+ {
+ moreBytes(0, 0, machInst);
+ }
+
+ bool
+ needMoreBytes()
+ {
+ return true;
+ }
+
+ bool
+ extMachInstReady()
+ {
+ return true;
+ }
+
+ // This returns a constant reference to the ExtMachInst to avoid a copy
+ const ExtMachInst &
+ getExtMachInst()
+ {
+ return emi;
+ }
+};
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_PREDECODER_HH__
diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc
new file mode 100644
index 000000000..92f993e4c
--- /dev/null
+++ b/src/arch/power/process.cc
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2007-2008 The Florida State University
+ * Copyright (c) 2009 The University of Edinburgh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Stephen Hines
+ * Timothy M. Jones
+ */
+
+#include "arch/power/isa_traits.hh"
+#include "arch/power/process.hh"
+#include "arch/power/types.hh"
+#include "base/loader/elf_object.hh"
+#include "base/loader/object_file.hh"
+#include "base/misc.hh"
+#include "cpu/thread_context.hh"
+#include "mem/page_table.hh"
+#include "mem/translating_port.hh"
+#include "sim/process_impl.hh"
+#include "sim/system.hh"
+
+using namespace std;
+using namespace PowerISA;
+
+PowerLiveProcess::PowerLiveProcess(LiveProcessParams *params,
+ ObjectFile *objFile)
+ : LiveProcess(params, objFile)
+{
+ stack_base = 0xbf000000L;
+
+ // Set pointer for next thread stack. Reserve 8M for main stack.
+ next_thread_stack_base = stack_base - (8 * 1024 * 1024);
+
+ // Set up break point (Top of Heap)
+ brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
+ brk_point = roundUp(brk_point, VMPageSize);
+
+ // Set up region for mmaps. For now, start at bottom of kuseg space.
+ mmap_start = mmap_end = 0x70000000L;
+}
+
+void
+PowerLiveProcess::startup()
+{
+ argsInit(MachineBytes, VMPageSize);
+}
+
+void
+PowerLiveProcess::argsInit(int intSize, int pageSize)
+{
+ typedef AuxVector<uint32_t> auxv_t;
+ std::vector<auxv_t> auxv;
+
+ string filename;
+ if (argv.size() < 1)
+ filename = "";
+ else
+ filename = argv[0];
+
+ //We want 16 byte alignment
+ uint64_t align = 16;
+
+ // Overloaded argsInit so that we can fine-tune for POWER architecture
+ Process::startup();
+
+ // load object file into target memory
+ objFile->loadSections(initVirtMem);
+
+ //Setup the auxilliary vectors. These will already have endian conversion.
+ //Auxilliary vectors are loaded only for elf formatted executables.
+ ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
+ if (elfObject) {
+ uint32_t features = 0;
+
+ //Bits which describe the system hardware capabilities
+ //XXX Figure out what these should be
+ auxv.push_back(auxv_t(M5_AT_HWCAP, features));
+ //The system page size
+ auxv.push_back(auxv_t(M5_AT_PAGESZ, PowerISA::VMPageSize));
+ //Frequency at which times() increments
+ auxv.push_back(auxv_t(M5_AT_CLKTCK, 0x64));
+ // For statically linked executables, this is the virtual address of the
+ // program header tables if they appear in the executable image
+ auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable()));
+ // This is the size of a program header entry from the elf file.
+ auxv.push_back(auxv_t(M5_AT_PHENT, elfObject->programHeaderSize()));
+ // This is the number of program headers from the original elf file.
+ auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount()));
+ //This is the address of the elf "interpreter", It should be set
+ //to 0 for regular executables. It should be something else
+ //(not sure what) for dynamic libraries.
+ auxv.push_back(auxv_t(M5_AT_BASE, 0));
+
+ //XXX Figure out what this should be.
+ auxv.push_back(auxv_t(M5_AT_FLAGS, 0));
+ //The entry point to the program
+ auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint()));
+ //Different user and group IDs
+ auxv.push_back(auxv_t(M5_AT_UID, uid()));
+ auxv.push_back(auxv_t(M5_AT_EUID, euid()));
+ auxv.push_back(auxv_t(M5_AT_GID, gid()));
+ auxv.push_back(auxv_t(M5_AT_EGID, egid()));
+ //Whether to enable "secure mode" in the executable
+ auxv.push_back(auxv_t(M5_AT_SECURE, 0));
+ //The filename of the program
+ auxv.push_back(auxv_t(M5_AT_EXECFN, 0));
+ //The string "v51" with unknown meaning
+ auxv.push_back(auxv_t(M5_AT_PLATFORM, 0));
+ }
+
+ //Figure out how big the initial stack nedes to be
+
+ // A sentry NULL void pointer at the top of the stack.
+ int sentry_size = intSize;
+
+ string platform = "v51";
+ int platform_size = platform.size() + 1;
+
+ // The aux vectors are put on the stack in two groups. The first group are
+ // the vectors that are generated as the elf is loaded. The second group
+ // are the ones that were computed ahead of time and include the platform
+ // string.
+ int aux_data_size = filename.size() + 1;
+
+ int env_data_size = 0;
+ for (int i = 0; i < envp.size(); ++i) {
+ env_data_size += envp[i].size() + 1;
+ }
+ int arg_data_size = 0;
+ for (int i = 0; i < argv.size(); ++i) {
+ arg_data_size += argv[i].size() + 1;
+ }
+
+ int info_block_size =
+ sentry_size + env_data_size + arg_data_size +
+ aux_data_size + platform_size;
+
+ //Each auxilliary vector is two 4 byte words
+ int aux_array_size = intSize * 2 * (auxv.size() + 1);
+
+ int envp_array_size = intSize * (envp.size() + 1);
+ int argv_array_size = intSize * (argv.size() + 1);
+
+ int argc_size = intSize;
+
+ //Figure out the size of the contents of the actual initial frame
+ int frame_size =
+ info_block_size +
+ aux_array_size +
+ envp_array_size +
+ argv_array_size +
+ argc_size;
+
+ //There needs to be padding after the auxiliary vector data so that the
+ //very bottom of the stack is aligned properly.
+ int partial_size = frame_size;
+ int aligned_partial_size = roundUp(partial_size, align);
+ int aux_padding = aligned_partial_size - partial_size;
+
+ int space_needed = frame_size + aux_padding;
+
+ stack_min = stack_base - space_needed;
+ stack_min = roundDown(stack_min, align);
+ stack_size = stack_base - stack_min;
+
+ // map memory
+ pTable->allocate(roundDown(stack_min, pageSize),
+ roundUp(stack_size, pageSize));
+
+ // map out initial stack contents
+ uint32_t sentry_base = stack_base - sentry_size;
+ uint32_t aux_data_base = sentry_base - aux_data_size;
+ uint32_t env_data_base = aux_data_base - env_data_size;
+ uint32_t arg_data_base = env_data_base - arg_data_size;
+ uint32_t platform_base = arg_data_base - platform_size;
+ uint32_t auxv_array_base = platform_base - aux_array_size - aux_padding;
+ uint32_t envp_array_base = auxv_array_base - envp_array_size;
+ uint32_t argv_array_base = envp_array_base - argv_array_size;
+ uint32_t argc_base = argv_array_base - argc_size;
+
+ DPRINTF(Stack, "The addresses of items on the initial stack:\n");
+ DPRINTF(Stack, "0x%x - aux data\n", aux_data_base);
+ DPRINTF(Stack, "0x%x - env data\n", env_data_base);
+ DPRINTF(Stack, "0x%x - arg data\n", arg_data_base);
+ DPRINTF(Stack, "0x%x - platform base\n", platform_base);
+ DPRINTF(Stack, "0x%x - auxv array\n", auxv_array_base);
+ DPRINTF(Stack, "0x%x - envp array\n", envp_array_base);
+ DPRINTF(Stack, "0x%x - argv array\n", argv_array_base);
+ DPRINTF(Stack, "0x%x - argc \n", argc_base);
+ DPRINTF(Stack, "0x%x - stack min\n", stack_min);
+
+ // write contents to stack
+
+ // figure out argc
+ uint32_t argc = argv.size();
+ uint32_t guestArgc = PowerISA::htog(argc);
+
+ //Write out the sentry void *
+ uint32_t sentry_NULL = 0;
+ initVirtMem->writeBlob(sentry_base,
+ (uint8_t*)&sentry_NULL, sentry_size);
+
+ //Fix up the aux vectors which point to other data
+ for (int i = auxv.size() - 1; i >= 0; i--) {
+ if (auxv[i].a_type == M5_AT_PLATFORM) {
+ auxv[i].a_val = platform_base;
+ initVirtMem->writeString(platform_base, platform.c_str());
+ } else if (auxv[i].a_type == M5_AT_EXECFN) {
+ auxv[i].a_val = aux_data_base;
+ initVirtMem->writeString(aux_data_base, filename.c_str());
+ }
+ }
+
+ //Copy the aux stuff
+ for (int x = 0; x < auxv.size(); x++)
+ {
+ initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize,
+ (uint8_t*)&(auxv[x].a_type), intSize);
+ initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize,
+ (uint8_t*)&(auxv[x].a_val), intSize);
+ }
+ //Write out the terminating zeroed auxilliary vector
+ const uint64_t zero = 0;
+ initVirtMem->writeBlob(auxv_array_base + 2 * intSize * auxv.size(),
+ (uint8_t*)&zero, 2 * intSize);
+
+ copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
+ copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
+
+ initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize);
+
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
+
+ //Set the stack pointer register
+ tc->setIntReg(StackPointerReg, stack_min);
+
+ Addr prog_entry = objFile->entryPoint();
+ tc->setPC(prog_entry);
+ tc->setNextPC(prog_entry + sizeof(MachInst));
+
+ //Align the "stack_min" to a page boundary.
+ stack_min = roundDown(stack_min, pageSize);
+}
+
+PowerISA::IntReg
+PowerLiveProcess::getSyscallArg(ThreadContext *tc, int &i)
+{
+ assert(i < 5);
+ return tc->readIntReg(ArgumentReg0 + i++);
+}
+
+void
+PowerLiveProcess::setSyscallArg(ThreadContext *tc,
+ int i, PowerISA::IntReg val)
+{
+ assert(i < 5);
+ tc->setIntReg(ArgumentReg0 + i, val);
+}
+
+void
+PowerLiveProcess::setSyscallReturn(ThreadContext *tc,
+ SyscallReturn return_value)
+{
+ tc->setIntReg(ReturnValueReg, return_value.value());
+}
diff --git a/src/arch/power/process.hh b/src/arch/power/process.hh
new file mode 100644
index 000000000..ede75f05f
--- /dev/null
+++ b/src/arch/power/process.hh
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007-2008 The Florida State University
+ * Copyright (c) 2009 The University of Edinburgh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Stephen Hines
+ * Timothy M. Jones
+ */
+
+#ifndef __POWER_PROCESS_HH__
+#define __POWER_PROCESS_HH__
+
+#include <string>
+#include <vector>
+#include "sim/process.hh"
+
+class LiveProcess;
+class ObjectFile;
+class System;
+
+class PowerLiveProcess : public LiveProcess
+{
+ protected:
+ PowerLiveProcess(LiveProcessParams * params, ObjectFile *objFile);
+
+ void startup();
+
+ public:
+ void argsInit(int intSize, int pageSize);
+ PowerISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
+ void setSyscallArg(ThreadContext *tc, int i, PowerISA::IntReg val);
+ void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
+};
+
+#endif // __POWER_PROCESS_HH__
+
diff --git a/src/arch/power/registers.hh b/src/arch/power/registers.hh
new file mode 100644
index 000000000..5bcca3641
--- /dev/null
+++ b/src/arch/power/registers.hh
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2009 The University of Edinburgh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Timothy M. Jones
+ */
+
+#ifndef __ARCH_POWER_REGISTERS_HH__
+#define __ARCH_POWER_REGISTERS_HH__
+
+#include "arch/power/max_inst_regs.hh"
+#include "arch/power/miscregs.hh"
+
+namespace PowerISA {
+
+using PowerISAInst::MaxInstSrcRegs;
+using PowerISAInst::MaxInstDestRegs;
+
+typedef uint8_t RegIndex;
+
+typedef uint64_t IntReg;
+
+// Floating point register file entry type
+typedef uint64_t FloatRegBits;
+typedef double FloatReg;
+typedef uint64_t MiscReg;
+
+// Constants Related to the number of registers
+const int NumIntArchRegs = 32;
+
+// CR, XER, LR, CTR, FPSCR, RSV, RSV-LEN, RSV-ADDR
+// and zero register, which doesn't actually exist but needs a number
+const int NumIntSpecialRegs = 9;
+const int NumFloatArchRegs = 32;
+const int NumFloatSpecialRegs = 0;
+const int NumInternalProcRegs = 0;
+
+const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs;
+const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;
+const int NumMiscRegs = NUM_MISCREGS;
+
+// Semantically meaningful register indices
+const int ReturnValueReg = 3;
+const int ArgumentReg0 = 3;
+const int ArgumentReg1 = 4;
+const int ArgumentReg2 = 5;
+const int ArgumentReg3 = 6;
+const int ArgumentReg4 = 7;
+const int FramePointerReg = 31;
+const int StackPointerReg = 1;
+
+// There isn't one in Power, but we need to define one somewhere
+const int ZeroReg = NumIntRegs - 1;
+
+const int SyscallNumReg = 0;
+const int SyscallPseudoReturnReg = 3;
+const int SyscallSuccessReg = 3;
+
+// These help enumerate all the registers for dependence tracking.
+const int FP_Base_DepTag = NumIntRegs;
+const int Ctrl_Base_DepTag = FP_Base_DepTag + NumFloatRegs;
+
+typedef union {
+ IntReg intreg;
+ FloatReg fpreg;
+ MiscReg ctrlreg;
+} AnyReg;
+
+enum MiscIntRegNums {
+ INTREG_CR = NumIntArchRegs,
+ INTREG_XER,
+ INTREG_LR,
+ INTREG_CTR,
+ INTREG_FPSCR,
+ INTREG_RSV,
+ INTREG_RSV_LEN,
+ INTREG_RSV_ADDR
+};
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_REGISTERS_HH__
diff --git a/src/mem/slicc/ast/TypeAST.hh b/src/arch/power/remote_gdb.hh
index f8e1fdc24..34bb4bd1f 100644
--- a/src/mem/slicc/ast/TypeAST.hh
+++ b/src/arch/power/remote_gdb.hh
@@ -1,6 +1,7 @@
-
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * Copyright (c) 2009 The University of Edinburgh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,59 +26,59 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * TypeAST.hh
- *
- * Description:
- *
- * $Id: TypeAST.hh,v 3.2 2003/03/22 15:15:17 xu Exp $
*
+ * Authors: Nathan Binkert
+ * Stephen Hines
+ * Timothy M. Jones
*/
-#ifndef TYPEAST_H
-#define TYPEAST_H
+#ifndef __ARCH_ARM_REMOTE_GDB_HH__
+#define __ARCH_ARM_REMOTE_GDB_HH__
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/AST.hh"
+#include "base/remote_gdb.hh"
-class TypeAST : public AST {
-public:
- // Constructors
- TypeAST(string* ident_ptr);
-
- // Destructor
- ~TypeAST();
+namespace PowerISA
+{
- // Public Methods
- string toString() const;
- Type* lookupType() const;
+class RemoteGDB : public BaseRemoteGDB
+{
+ public:
+ RemoteGDB(System *system, ThreadContext *context)
+ : BaseRemoteGDB(system, context, 1)
+ {
+ }
- virtual void print(ostream& out) const {}
-private:
- // Private Methods
+ bool
+ acc(Addr, size_t)
+ {
+ panic("acc not implemented for POWER!");
+ }
- // Private copy constructor and assignment operator
- TypeAST(const TypeAST& obj);
- TypeAST& operator=(const TypeAST& obj);
+ void
+ getregs()
+ {
+ panic("getregs not implemented for POWER!");
+ }
- // Data Members (m_ prefix)
- string* m_ident_ptr;
-};
+ void
+ setregs()
+ {
+ panic("setregs not implemented for POWER!");
+ }
-// Output operator declaration
-ostream& operator<<(ostream& out, const TypeAST& obj);
+ void
+ clearSingleStep()
+ {
+ panic("clearSingleStep not implemented for POWER!");
+ }
-// ******************* Definitions *******************
+ void
+ setSingleStep()
+ {
+ panic("setSingleStep not implemented for POWER!");
+ }
+};
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const TypeAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
+} // PowerISA namespace
-#endif //TYPEAST_H
+#endif /* __ARCH_POWER_REMOTE_GDB_H__ */
diff --git a/src/arch/power/stacktrace.hh b/src/arch/power/stacktrace.hh
new file mode 100644
index 000000000..49d687a6e
--- /dev/null
+++ b/src/arch/power/stacktrace.hh
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2005 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * Copyright (c) 2009 The University of Edinburgh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ali Saidi
+ * Stephen Hines
+ * Timothy M. Jones
+ */
+
+#ifndef __ARCH_POWER_STACKTRACE_HH__
+#define __ARCH_POWER_STACKTRACE_HH__
+
+#include "base/trace.hh"
+#include "cpu/static_inst.hh"
+
+class ThreadContext;
+class StackTrace;
+
+namespace PowerISA
+{
+
+class ProcessInfo
+{
+ private:
+ ThreadContext *tc;
+
+ int thread_info_size;
+ int task_struct_size;
+ int task_off;
+ int pid_off;
+ int name_off;
+
+ public:
+ ProcessInfo(ThreadContext *_tc);
+
+ Addr task(Addr ksp) const;
+ int pid(Addr ksp) const;
+ std::string name(Addr ksp) const;
+};
+
+class StackTrace
+{
+ protected:
+ typedef TheISA::MachInst MachInst;
+ private:
+ ThreadContext *tc;
+ std::vector<Addr> stack;
+
+ private:
+ bool isEntry(Addr addr);
+ bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra);
+ bool decodeSave(MachInst inst, int &reg, int &disp);
+ bool decodeStack(MachInst inst, int &disp);
+
+ void trace(ThreadContext *tc, bool is_call);
+
+ public:
+ StackTrace();
+ StackTrace(ThreadContext *tc, StaticInstPtr inst);
+ ~StackTrace();
+
+ void
+ clear()
+ {
+ tc = 0;
+ stack.clear();
+ }
+
+ bool
+ valid() const
+ {
+ return tc != NULL;
+ }
+
+ bool trace(ThreadContext *tc, StaticInstPtr inst);
+
+ public:
+ const std::vector<Addr> &
+ getstack() const
+ {
+ return stack;
+ }
+
+ static const int user = 1;
+ static const int console = 2;
+ static const int unknown = 3;
+
+#if TRACING_ON
+ private:
+ void dump();
+
+ public:
+ void
+ dprintf()
+ {
+ if (DTRACE(Stack))
+ dump();
+ }
+#else
+ public:
+ void
+ dprintf()
+ {
+ }
+#endif
+};
+
+inline bool
+StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
+{
+ if (!inst->isCall() && !inst->isReturn())
+ return false;
+
+ if (valid())
+ clear();
+
+ trace(tc, !inst->isReturn());
+ return true;
+}
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_STACKTRACE_HH__
diff --git a/src/arch/power/tlb.cc b/src/arch/power/tlb.cc
new file mode 100644
index 000000000..125c92a1a
--- /dev/null
+++ b/src/arch/power/tlb.cc
@@ -0,0 +1,322 @@
+/*
+ * Copyright (c) 2001-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007 MIPS Technologies, Inc.
+ * Copyright (c) 2007-2008 The Florida State University
+ * Copyright (c) 2009 The University of Edinburgh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
+ * Steve Reinhardt
+ * Jaidev Patwardhan
+ * Stephen Hines
+ * Timothy M. Jones
+ */
+
+#include <string>
+#include <vector>
+
+#include "arch/power/faults.hh"
+#include "arch/power/pagetable.hh"
+#include "arch/power/tlb.hh"
+#include "arch/power/utility.hh"
+#include "base/inifile.hh"
+#include "base/str.hh"
+#include "base/trace.hh"
+#include "cpu/thread_context.hh"
+#include "mem/page_table.hh"
+#include "params/PowerTLB.hh"
+#include "sim/process.hh"
+
+
+using namespace std;
+using namespace PowerISA;
+
+///////////////////////////////////////////////////////////////////////
+//
+// POWER TLB
+//
+
+#define MODE2MASK(X) (1 << (X))
+
+TLB::TLB(const Params *p)
+ : BaseTLB(p), size(p->size), nlu(0)
+{
+ table = new PowerISA::PTE[size];
+ memset(table, 0, sizeof(PowerISA::PTE[size]));
+ smallPages = 0;
+}
+
+TLB::~TLB()
+{
+ if (table)
+ delete [] table;
+}
+
+// look up an entry in the TLB
+PowerISA::PTE *
+TLB::lookup(Addr vpn, uint8_t asn) const
+{
+ // assume not found...
+ PowerISA::PTE *retval = NULL;
+ PageTable::const_iterator i = lookupTable.find(vpn);
+ if (i != lookupTable.end()) {
+ while (i->first == vpn) {
+ int index = i->second;
+ PowerISA::PTE *pte = &table[index];
+ Addr Mask = pte->Mask;
+ Addr InvMask = ~Mask;
+ Addr VPN = pte->VPN;
+ if (((vpn & InvMask) == (VPN & InvMask))
+ && (pte->G || (asn == pte->asid))) {
+
+ // We have a VPN + ASID Match
+ retval = pte;
+ break;
+ }
+ ++i;
+ }
+ }
+
+ DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn,
+ retval ? "hit" : "miss", retval ? retval->PFN1 : 0);
+ return retval;
+}
+
+PowerISA::PTE*
+TLB::getEntry(unsigned Index) const
+{
+ // Make sure that Index is valid
+ assert(Index<size);
+ return &table[Index];
+}
+
+int
+TLB::probeEntry(Addr vpn,uint8_t asn) const
+{
+ // assume not found...
+ PowerISA::PTE *retval = NULL;
+ int Ind = -1;
+ PageTable::const_iterator i = lookupTable.find(vpn);
+ if (i != lookupTable.end()) {
+ while (i->first == vpn) {
+ int index = i->second;
+ PowerISA::PTE *pte = &table[index];
+ Addr Mask = pte->Mask;
+ Addr InvMask = ~Mask;
+ Addr VPN = pte->VPN;
+ if (((vpn & InvMask) == (VPN & InvMask))
+ && (pte->G || (asn == pte->asid))) {
+
+ // We have a VPN + ASID Match
+ retval = pte;
+ Ind = index;
+ break;
+ }
+ ++i;
+ }
+ }
+
+ DPRINTF(Power, "VPN: %x, asid: %d, Result of TLBP: %d\n", vpn, asn, Ind);
+ return Ind;
+}
+
+inline Fault
+TLB::checkCacheability(RequestPtr &req)
+{
+ Addr VAddrUncacheable = 0xA0000000;
+ if ((req->getVaddr() & VAddrUncacheable) == VAddrUncacheable) {
+
+ // mark request as uncacheable
+ req->setFlags(Request::UNCACHEABLE);
+ }
+ return NoFault;
+}
+
+void
+TLB::insertAt(PowerISA::PTE &pte, unsigned Index, int _smallPages)
+{
+ smallPages=_smallPages;
+ if (Index > size){
+ warn("Attempted to write at index (%d) beyond TLB size (%d)",
+ Index, size);
+ } else {
+
+ // Update TLB
+ if (table[Index].V0 == true || table[Index].V1 == true) {
+
+ // Previous entry is valid
+ PageTable::iterator i = lookupTable.find(table[Index].VPN);
+ lookupTable.erase(i);
+ }
+ table[Index]=pte;
+
+ // Update fast lookup table
+ lookupTable.insert(make_pair(table[Index].VPN, Index));
+ }
+}
+
+// insert a new TLB entry
+void
+TLB::insert(Addr addr, PowerISA::PTE &pte)
+{
+ fatal("TLB Insert not yet implemented\n");
+}
+
+void
+TLB::flushAll()
+{
+ DPRINTF(TLB, "flushAll\n");
+ memset(table, 0, sizeof(PowerISA::PTE[size]));
+ lookupTable.clear();
+ nlu = 0;
+}
+
+void
+TLB::serialize(ostream &os)
+{
+ SERIALIZE_SCALAR(size);
+ SERIALIZE_SCALAR(nlu);
+
+ for (int i = 0; i < size; i++) {
+ nameOut(os, csprintf("%s.PTE%d", name(), i));
+ table[i].serialize(os);
+ }
+}
+
+void
+TLB::unserialize(Checkpoint *cp, const string &section)
+{
+ UNSERIALIZE_SCALAR(size);
+ UNSERIALIZE_SCALAR(nlu);
+
+ for (int i = 0; i < size; i++) {
+ table[i].unserialize(cp, csprintf("%s.PTE%d", section, i));
+ if (table[i].V0 || table[i].V1) {
+ lookupTable.insert(make_pair(table[i].VPN, i));
+ }
+ }
+}
+
+void
+TLB::regStats()
+{
+ read_hits
+ .name(name() + ".read_hits")
+ .desc("DTB read hits")
+ ;
+
+ read_misses
+ .name(name() + ".read_misses")
+ .desc("DTB read misses")
+ ;
+
+
+ read_accesses
+ .name(name() + ".read_accesses")
+ .desc("DTB read accesses")
+ ;
+
+ write_hits
+ .name(name() + ".write_hits")
+ .desc("DTB write hits")
+ ;
+
+ write_misses
+ .name(name() + ".write_misses")
+ .desc("DTB write misses")
+ ;
+
+
+ write_accesses
+ .name(name() + ".write_accesses")
+ .desc("DTB write accesses")
+ ;
+
+ hits
+ .name(name() + ".hits")
+ .desc("DTB hits")
+ ;
+
+ misses
+ .name(name() + ".misses")
+ .desc("DTB misses")
+ ;
+
+ invalids
+ .name(name() + ".invalids")
+ .desc("DTB access violations")
+ ;
+
+ accesses
+ .name(name() + ".accesses")
+ .desc("DTB accesses")
+ ;
+
+ hits = read_hits + write_hits;
+ misses = read_misses + write_misses;
+ accesses = read_accesses + write_accesses;
+}
+
+Fault
+TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
+{
+#if !FULL_SYSTEM
+ Process * p = tc->getProcessPtr();
+
+ Fault fault = p->pTable->translate(req);
+ if (fault != NoFault)
+ return fault;
+
+ return NoFault;
+#else
+ fatal("translate atomic not yet implemented\n");
+#endif
+}
+
+void
+TLB::translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation, Mode mode)
+{
+ assert(translation);
+ translation->finish(translateAtomic(req, tc, mode), req, tc, mode);
+}
+
+PowerISA::PTE &
+TLB::index(bool advance)
+{
+ PowerISA::PTE *pte = &table[nlu];
+
+ if (advance)
+ nextnlu();
+
+ return *pte;
+}
+
+PowerISA::TLB *
+PowerTLBParams::create()
+{
+ return new PowerISA::TLB(this);
+}
diff --git a/src/arch/power/tlb.hh b/src/arch/power/tlb.hh
new file mode 100644
index 000000000..8b6c7233d
--- /dev/null
+++ b/src/arch/power/tlb.hh
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2001-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007 MIPS Technologies, Inc.
+ * Copyright (c) 2007-2008 The Florida State University
+ * Copyright (c) 2009 The University of Edinburgh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
+ * Steve Reinhardt
+ * Stephen Hines
+ * Timothy M. Jones
+ */
+
+#ifndef __ARCH_POWER_TLB_HH__
+#define __ARCH_POWER_TLB_HH__
+
+#include <map>
+
+#include "arch/power/isa_traits.hh"
+#include "arch/power/utility.hh"
+#include "arch/power/vtophys.hh"
+#include "arch/power/pagetable.hh"
+#include "base/statistics.hh"
+#include "mem/request.hh"
+#include "params/PowerTLB.hh"
+#include "sim/faults.hh"
+#include "sim/tlb.hh"
+
+class ThreadContext;
+
+namespace PowerISA {
+
+// This is copied from the ARM ISA and has not been checked against the
+// Power at all.
+struct TlbEntry
+{
+ Addr _pageStart;
+
+ TlbEntry()
+ {
+ }
+
+ TlbEntry(Addr asn, Addr vaddr, Addr paddr)
+ : _pageStart(paddr)
+ {
+ }
+
+ void
+ updateVaddr(Addr new_vaddr)
+ {
+ panic("unimplemented");
+ }
+
+ Addr
+ pageStart()
+ {
+ return _pageStart;
+ }
+
+ void
+ serialize(std::ostream &os)
+ {
+ SERIALIZE_SCALAR(_pageStart);
+ }
+
+ void
+ unserialize(Checkpoint *cp, const std::string &section)
+ {
+ UNSERIALIZE_SCALAR(_pageStart);
+ }
+};
+
+class TLB : public BaseTLB
+{
+ protected:
+ typedef std::multimap<Addr, int> PageTable;
+ PageTable lookupTable; // Quick lookup into page table
+
+ PowerISA::PTE *table; // the Page Table
+ int size; // TLB Size
+ int nlu; // not last used entry (for replacement)
+
+ void
+ nextnlu()
+ {
+ if (++nlu >= size) {
+ nlu = 0;
+ }
+ }
+
+ PowerISA::PTE *lookup(Addr vpn, uint8_t asn) const;
+
+ mutable Stats::Scalar read_hits;
+ mutable Stats::Scalar read_misses;
+ mutable Stats::Scalar read_acv;
+ mutable Stats::Scalar read_accesses;
+ mutable Stats::Scalar write_hits;
+ mutable Stats::Scalar write_misses;
+ mutable Stats::Scalar write_acv;
+ mutable Stats::Scalar write_accesses;
+ Stats::Formula hits;
+ Stats::Formula misses;
+ Stats::Formula invalids;
+ Stats::Formula accesses;
+
+ public:
+ typedef PowerTLBParams Params;
+ TLB(const Params *p);
+ virtual ~TLB();
+
+ int probeEntry(Addr vpn,uint8_t) const;
+ PowerISA::PTE *getEntry(unsigned) const;
+
+ int smallPages;
+
+ int
+ getsize() const
+ {
+ return size;
+ }
+
+ PowerISA::PTE &index(bool advance = true);
+ void insert(Addr vaddr, PowerISA::PTE &pte);
+ void insertAt(PowerISA::PTE &pte, unsigned Index, int _smallPages);
+ void flushAll();
+
+ void
+ demapPage(Addr vaddr, uint64_t asn)
+ {
+ panic("demapPage unimplemented.\n");
+ }
+
+ // static helper functions... really
+ static bool validVirtualAddress(Addr vaddr);
+ static Fault checkCacheability(RequestPtr &req);
+ Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode);
+ void translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation, Mode mode);
+
+ // Checkpointing
+ void serialize(std::ostream &os);
+ void unserialize(Checkpoint *cp, const std::string &section);
+ void regStats();
+};
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_TLB_HH__
diff --git a/src/mem/slicc/ast/ExprAST.hh b/src/arch/power/types.hh
index 9566541da..7b994adc9 100644
--- a/src/mem/slicc/ast/ExprAST.hh
+++ b/src/arch/power/types.hh
@@ -1,6 +1,5 @@
-
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009 The University of Edinburgh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,60 +24,68 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * ExprAST.hh
- *
- * Description:
- *
- * $Id$
*
+ * Authors: Timothy M. Jones
*/
-#ifndef EXPRAST_H
-#define EXPRAST_H
+#ifndef __ARCH_POWER_TYPES_HH__
+#define __ARCH_POWER_TYPES_HH__
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/AST.hh"
+#include "base/bitunion.hh"
+#include "base/types.hh"
+namespace PowerISA
+{
-class ExprAST : public AST {
-public:
- // Constructors
- ExprAST() : AST() { }
+typedef uint32_t MachInst;
- // Destructor
- virtual ~ExprAST() { }
+BitUnion32(ExtMachInst)
- // Public Methods
- virtual Type* generate(string& code) const = 0;
- virtual void findResources(Map<Var*, string>& resource_list) const {} // The default is no resources
+ // Registers
+ Bitfield<25, 21> rs;
+ Bitfield<20, 16> ra;
- // void print(ostream& out) const;
-private:
- // Private Methods
+ // Shifts and masks
+ Bitfield<15, 11> sh;
+ Bitfield<10, 6> mb;
+ Bitfield< 5, 1> me;
- // Private copy constructor and assignment operator
- // ExprAST(const ExprAST& obj);
- // ExprAST& operator=(const ExprAST& obj);
+ // Immediate fields
+ Bitfield<15, 0> si;
+ Bitfield<15, 0> d;
- // Data Members (m_ prefix)
+ // Special purpose register identifier
+ Bitfield<20, 11> spr;
+ Bitfield<25, 2> li;
+ Bitfield<1> aa;
+ Bitfield<25, 23> bf;
+ Bitfield<15, 2> bd;
+ Bitfield<25, 21> bo;
+ Bitfield<20, 16> bi;
+ Bitfield<20, 18> bfa;
-};
+ // Record bits
+ Bitfield<0> rc31;
+ Bitfield<10> oe;
-// Output operator declaration
-ostream& operator<<(ostream& out, const ExprAST& obj);
+ // Condition register fields
+ Bitfield<25, 21> bt;
+ Bitfield<20, 16> ba;
+ Bitfield<15, 11> bb;
-// ******************* Definitions *******************
+ // FXM field for mtcrf instruction
+ Bitfield<19, 12> fxm;
+EndBitUnion(ExtMachInst)
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const ExprAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
+// typedef uint64_t LargestRead;
+// // Need to use 64 bits to make sure that read requests get handled properly
+
+// typedef int RegContextParam;
+// typedef int RegContextVal;
+
+struct CoreSpecific {
+};
+
+} // PowerISA namspace
-#endif //EXPRAST_H
+#endif // __ARCH_POWER_TYPES_HH__
diff --git a/src/arch/power/utility.hh b/src/arch/power/utility.hh
new file mode 100644
index 000000000..442075aa2
--- /dev/null
+++ b/src/arch/power/utility.hh
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * Copyright (c) 2009 The University of Edinburgh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Korey Sewell
+ * Stephen Hines
+ * Timothy M. Jones
+ */
+
+#ifndef __ARCH_POWER_UTILITY_HH__
+#define __ARCH_POWER_UTILITY_HH__
+
+#include "arch/power/miscregs.hh"
+#include "arch/power/types.hh"
+#include "base/hashmap.hh"
+#include "base/types.hh"
+#include "cpu/thread_context.hh"
+
+namespace __hash_namespace {
+
+template<>
+struct hash<PowerISA::ExtMachInst> : public hash<uint32_t> {
+ size_t operator()(const PowerISA::ExtMachInst &emi) const {
+ return hash<uint32_t>::operator()((uint32_t)emi);
+ };
+};
+
+} // __hash_namespace namespace
+
+namespace PowerISA {
+
+/**
+ * Function to ensure ISA semantics about 0 registers.
+ * @param tc The thread context.
+ */
+template <class TC>
+void zeroRegisters(TC *tc);
+
+// Instruction address compression hooks
+static inline Addr
+realPCToFetchPC(const Addr &addr)
+{
+ return addr;
+}
+
+static inline Addr
+fetchPCToRealPC(const Addr &addr)
+{
+ return addr;
+}
+
+// the size of "fetched" instructions
+static inline size_t
+fetchInstSize()
+{
+ return sizeof(MachInst);
+}
+
+static inline MachInst
+makeRegisterCopy(int dest, int src)
+{
+ panic("makeRegisterCopy not implemented");
+ return 0;
+}
+
+inline void
+startupCPU(ThreadContext *tc, int cpuId)
+{
+ tc->activate(0);
+}
+
+template <class XC>
+Fault
+checkFpEnableFault(XC *xc)
+{
+ return NoFault;
+}
+
+static inline void
+copyRegs(ThreadContext *src, ThreadContext *dest)
+{
+ panic("Copy Regs Not Implemented Yet\n");
+}
+
+static inline void
+copyMiscRegs(ThreadContext *src, ThreadContext *dest)
+{
+ panic("Copy Misc. Regs Not Implemented Yet\n");
+}
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_UTILITY_HH__
diff --git a/src/arch/power/vtophys.hh b/src/arch/power/vtophys.hh
new file mode 100644
index 000000000..3cfebcfc7
--- /dev/null
+++ b/src/arch/power/vtophys.hh
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * Copyright (c) 2007-2008 The Florida State University
+ * Copyright (c) 2009 The University of Edinburgh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ali Saidi
+ * Nathan Binkert
+ * Stephen Hines
+ * Timothy M. Jones
+ */
+
+#ifndef __ARCH_POWER_VTOPHYS_HH__
+#define __ARCH_POWER_VTOPHYS_HH__
+
+#include "arch/power/isa_traits.hh"
+#include "arch/power/utility.hh"
+
+
+class ThreadContext;
+class FunctionalPort;
+
+namespace PowerISA {
+
+inline Addr
+PteAddr(Addr a)
+{
+ return (a & PteMask) << PteShift;
+}
+
+} // PowerISA namespace
+
+#endif // __ARCH_POWER_VTOPHYS_HH__
+
diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa
index e34ca033f..ce5e34ff0 100644
--- a/src/arch/sparc/isa/decoder.isa
+++ b/src/arch/sparc/isa/decoder.isa
@@ -226,7 +226,8 @@ decode OP default Unknown::unknown()
if(Rs2_or_imm13.udw == 0) fault = new DivisionByZero;
else Rd = Rs1.udw / Rs2_or_imm13.udw;}});
0x1E: IntOpCcRes::udivcc({{
- uint32_t resTemp, val2 = Rs2_or_imm13.udw;
+ uint64_t resTemp;
+ uint32_t val2 = Rs2_or_imm13.udw;
int32_t overflow = 0;
if(val2 == 0) fault = new DivisionByZero;
else
diff --git a/src/arch/sparc/linux/linux.hh b/src/arch/sparc/linux/linux.hh
index b1dc691ce..1f7567d43 100644
--- a/src/arch/sparc/linux/linux.hh
+++ b/src/arch/sparc/linux/linux.hh
@@ -77,6 +77,22 @@ class SparcLinux : public Linux
static const int NUM_OPEN_FLAGS;
static const unsigned TGT_MAP_ANONYMOUS = 0x20;
+
+ typedef struct {
+ int64_t uptime; /* Seconds since boot */
+ uint64_t loads[3]; /* 1, 5, and 15 minute load averages */
+ uint64_t totalram; /* Total usable main memory size */
+ uint64_t freeram; /* Available memory size */
+ uint64_t sharedram; /* Amount of shared memory */
+ uint64_t bufferram; /* Memory used by buffers */
+ uint64_t totalswap; /* Total swap space size */
+ uint64_t freeswap; /* swap space still available */
+ uint16_t procs; /* Number of current processes */
+ uint64_t totalhigh; /* Total high memory size */
+ uint64_t freehigh; /* Available high memory size */
+ uint64_t mem_unit; /* Memory unit size in bytes */
+ } tgt_sysinfo;
+
};
class Sparc32Linux : public SparcLinux
@@ -105,6 +121,22 @@ class Sparc32Linux : public SparcLinux
uint32_t __unused4;
uint32_t __unused5;
} tgt_stat64;
+
+ typedef struct {
+ int32_t uptime; /* Seconds since boot */
+ uint32_t loads[3]; /* 1, 5, and 15 minute load averages */
+ uint32_t totalram; /* Total usable main memory size */
+ uint32_t freeram; /* Available memory size */
+ uint32_t sharedram; /* Amount of shared memory */
+ uint32_t bufferram; /* Memory used by buffers */
+ uint32_t totalswap; /* Total swap space size */
+ uint32_t freeswap; /* swap space still available */
+ uint16_t procs; /* Number of current processes */
+ uint32_t totalhigh; /* Total high memory size */
+ uint32_t freehigh; /* Available high memory size */
+ uint32_t mem_unit; /* Memory unit size in bytes */
+ } tgt_sysinfo;
+
};
#endif
diff --git a/src/arch/sparc/linux/syscalls.cc b/src/arch/sparc/linux/syscalls.cc
index f4781d886..874ddc005 100644
--- a/src/arch/sparc/linux/syscalls.cc
+++ b/src/arch/sparc/linux/syscalls.cc
@@ -41,7 +41,8 @@ static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
+ int index = 0;
+ TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, index));
strcpy(name->sysname, "Linux");
strcpy(name->nodename, "m5.eecs.umich.edu");
@@ -59,9 +60,10 @@ SyscallReturn getresuidFunc(SyscallDesc *desc, int num,
LiveProcess *p, ThreadContext *tc)
{
const IntReg id = htog(100);
- Addr ruid = p->getSyscallArg(tc, 0);
- Addr euid = p->getSyscallArg(tc, 1);
- Addr suid = p->getSyscallArg(tc, 2);
+ int index = 0;
+ Addr ruid = p->getSyscallArg(tc, index);
+ Addr euid = p->getSyscallArg(tc, index);
+ Addr suid = p->getSyscallArg(tc, index);
//Handle the EFAULT case
//Set the ruid
if(ruid)
@@ -302,7 +304,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = {
/* 211 */ SyscallDesc("tgkill", unimplementedFunc), //32 bit
/* 212 */ SyscallDesc("waitpid", unimplementedFunc), //32 bit
/* 213 */ SyscallDesc("swapoff", unimplementedFunc),
- /* 214 */ SyscallDesc("sysinfo", unimplementedFunc), //32 bit
+ /* 214 */ SyscallDesc("sysinfo", sysinfoFunc<Sparc32Linux>), //32 bit
/* 215 */ SyscallDesc("ipc", unimplementedFunc), //32 bit
/* 216 */ SyscallDesc("sigreturn", unimplementedFunc), //32 bit
/* 217 */ SyscallDesc("clone", cloneFunc),
@@ -608,7 +610,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 211 */ SyscallDesc("tgkill", unimplementedFunc),
/* 212 */ SyscallDesc("waitpid", unimplementedFunc),
/* 213 */ SyscallDesc("swapoff", unimplementedFunc),
- /* 214 */ SyscallDesc("sysinfo", unimplementedFunc),
+ /* 214 */ SyscallDesc("sysinfo", sysinfoFunc<SparcLinux>),
/* 215 */ SyscallDesc("ipc", unimplementedFunc),
/* 216 */ SyscallDesc("sigreturn", unimplementedFunc),
/* 217 */ SyscallDesc("clone", cloneFunc),
diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc
index 89e853573..7e01f6b07 100644
--- a/src/arch/sparc/process.cc
+++ b/src/arch/sparc/process.cc
@@ -514,10 +514,10 @@ void Sparc64LiveProcess::flushWindows(ThreadContext *tc)
}
IntReg
-Sparc32LiveProcess::getSyscallArg(ThreadContext *tc, int i)
+Sparc32LiveProcess::getSyscallArg(ThreadContext *tc, int &i)
{
assert(i < 6);
- return bits(tc->readIntReg(FirstArgumentReg + i), 31, 0);
+ return bits(tc->readIntReg(FirstArgumentReg + i++), 31, 0);
}
void
@@ -528,10 +528,10 @@ Sparc32LiveProcess::setSyscallArg(ThreadContext *tc, int i, IntReg val)
}
IntReg
-Sparc64LiveProcess::getSyscallArg(ThreadContext *tc, int i)
+Sparc64LiveProcess::getSyscallArg(ThreadContext *tc, int &i)
{
assert(i < 6);
- return tc->readIntReg(FirstArgumentReg + i);
+ return tc->readIntReg(FirstArgumentReg + i++);
}
void
diff --git a/src/arch/sparc/process.hh b/src/arch/sparc/process.hh
index fdb9734ba..cca312e0a 100644
--- a/src/arch/sparc/process.hh
+++ b/src/arch/sparc/process.hh
@@ -95,7 +95,7 @@ class Sparc32LiveProcess : public SparcLiveProcess
void flushWindows(ThreadContext *tc);
- SparcISA::IntReg getSyscallArg(ThreadContext *tc, int i);
+ SparcISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
void setSyscallArg(ThreadContext *tc, int i, SparcISA::IntReg val);
};
@@ -123,7 +123,7 @@ class Sparc64LiveProcess : public SparcLiveProcess
void flushWindows(ThreadContext *tc);
- SparcISA::IntReg getSyscallArg(ThreadContext *tc, int i);
+ SparcISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
void setSyscallArg(ThreadContext *tc, int i, SparcISA::IntReg val);
};
diff --git a/src/arch/sparc/solaris/process.cc b/src/arch/sparc/solaris/process.cc
index eafb488df..24abd8687 100644
--- a/src/arch/sparc/solaris/process.cc
+++ b/src/arch/sparc/solaris/process.cc
@@ -48,7 +48,8 @@ static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- TypedBufferArg<Solaris::utsname> name(process->getSyscallArg(tc, 0));
+ int index = 0;
+ TypedBufferArg<Solaris::utsname> name(process->getSyscallArg(tc, index));
strcpy(name->sysname, "SunOS");
strcpy(name->nodename, "m5.eecs.umich.edu");
diff --git a/src/arch/x86/X86TLB.py b/src/arch/x86/X86TLB.py
index 15b03fd33..9f7dc43b3 100644
--- a/src/arch/x86/X86TLB.py
+++ b/src/arch/x86/X86TLB.py
@@ -53,13 +53,14 @@
#
# Authors: Gabe Black
-from MemObject import MemObject
+from m5.defines import buildEnv
from m5.params import *
from m5.proxy import *
-from m5 import build_env
+
from BaseTLB import BaseTLB
+from MemObject import MemObject
-if build_env['FULL_SYSTEM']:
+if buildEnv['FULL_SYSTEM']:
class X86PagetableWalker(MemObject):
type = 'X86PagetableWalker'
cxx_class = 'X86ISA::Walker'
@@ -70,6 +71,6 @@ class X86TLB(BaseTLB):
type = 'X86TLB'
cxx_class = 'X86ISA::TLB'
size = Param.Int(64, "TLB size")
- if build_env['FULL_SYSTEM']:
+ if buildEnv['FULL_SYSTEM']:
walker = Param.X86PagetableWalker(\
X86PagetableWalker(), "page table walker")
diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc
index 1b7933036..1b83c6649 100644
--- a/src/arch/x86/interrupts.cc
+++ b/src/arch/x86/interrupts.cc
@@ -500,7 +500,7 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val)
InterruptCommandRegHigh high = regs[APIC_INTERRUPT_COMMAND_HIGH];
// Record that an IPI is being sent.
low.deliveryStatus = 1;
- TriggerIntMessage message;
+ TriggerIntMessage message = 0;
message.destination = high.destination;
message.vector = low.vector;
message.deliveryMode = low.deliveryMode;
diff --git a/src/arch/x86/isa.cc b/src/arch/x86/isa.cc
index 06a656efc..47d24ed1e 100644
--- a/src/arch/x86/isa.cc
+++ b/src/arch/x86/isa.cc
@@ -41,7 +41,7 @@ void
ISA::updateHandyM5Reg(Efer efer, CR0 cr0,
SegAttr csAttr, SegAttr ssAttr, RFLAGS rflags)
{
- HandyM5Reg m5reg;
+ HandyM5Reg m5reg = 0;
if (efer.lma) {
m5reg.mode = LongMode;
if (csAttr.longMode)
diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa
index c23eeccab..288c5e5a8 100644
--- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa
+++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa
@@ -604,7 +604,7 @@
}
// repe (0xF3)
0x4: decode OPCODE_OP_BOTTOM3 {
- 0x7: WarnUnimpl::movdqu_Vo_Wo();
+ 0x7: MOVDQU(Vo,Wo);
default: UD2();
}
// operand size (0x66)
@@ -615,8 +615,8 @@
0x3: PACKSSDW(Vo,Wo);
0x4: PUNPCKLQDQ(Vo,Wq);
0x5: PUNPCKHQDQ(Vo,Wq);
- 0x6: WarnUnimpl::movd_Vo_Ed();
- 0x7: WarnUnimpl::movdqa_Vo_Wo();
+ 0x6: MOVD(Vo,Edp);
+ 0x7: MOVDQA(Vo,Wo);
}
default: UD2();
}
@@ -673,9 +673,9 @@
//0x3: group14_pshimq();
0x3: decode MODRM_REG {
0x2: PSRLQ(VRo,Ib);
- 0x3: WarnUnimpl::psrldq_VRo_Ib();
+ 0x3: PSRLDQ(VRo,Ib);
0x6: PSLLQ(VRo,Ib);
- 0x7: WarnUnimpl::pslldq_VRo_Ib();
+ 0x7: PSLLDQ(VRo,Ib);
default: UD2();
}
0x4: PCMPEQB(Vo,Wo);
@@ -702,15 +702,15 @@
// repe (0xF3)
0x4: decode OPCODE_OP_BOTTOM3 {
0x6: MOVQ(Vq,Wq);
- 0x7: WarnUnimpl::movdqu_Wo_Vo();
+ 0x7: MOVDQU(Wo,Vo);
default: UD2();
}
// operand size (0x66)
0x1: decode OPCODE_OP_BOTTOM3 {
- 0x4: WarnUnimpl::haddpd_Vo_Wo();
+ 0x4: HADDPD(Vo,Wo);
0x5: WarnUnimpl::hsubpd_Vo_Wo();
- 0x6: WarnUnimpl::movd_Ed_Vd();
- 0x7: WarnUnimpl::movdqa_Wo_Vo();
+ 0x6: MOVD(Edp,Vd);
+ 0x7: MOVDQA(Wo,Vo);
default: UD2();
}
// repne (0xF2)
diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py
index a9ad611b7..1c0650683 100644
--- a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py
+++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py
@@ -62,7 +62,7 @@ def macroop IRET_PROT {
.adjust_env oszIn64Override
# Check for a nested task. This isn't supported at the moment.
- rflag t1, NT
+ rflag t1, 14; #NT bit
panic "Task switching with iret is unimplemented!", flags=(nCEZF,)
#t1 = temp_RIP
diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py
index 7ccdca6c3..51f5ad23b 100644
--- a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py
+++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py
@@ -355,6 +355,36 @@ def macroop MOVNTI_P_R {
rdip t7
st reg, seg, riprel, disp
};
+
+def macroop MOVD_XMM_R {
+ mov2fp xmml, regm, srcSize=dsz, destSize=8
+ lfpimm xmmh, 0
+};
+
+def macroop MOVD_XMM_M {
+ ldfp xmml, seg, sib, disp, dataSize=dsz
+ lfpimm xmmh, 0
+};
+
+def macroop MOVD_XMM_P {
+ rdip t7
+ ldfp xmml, seg, riprel, disp, dataSize=dsz
+ lfpimm xmmh, 0
+};
+
+def macroop MOVD_R_XMM {
+ mov2int reg, xmmlm, size=dsz
+};
+
+def macroop MOVD_M_XMM {
+ stfp xmml, seg, sib, disp, dataSize=dsz
+};
+
+def macroop MOVD_P_XMM {
+ rdip t7
+ stfp xmml, seg, riprel, disp, dataSize=dsz
+};
+
'''
#let {{
# class MOVD(Inst):
diff --git a/src/arch/x86/isa/insts/simd128/floating_point/arithmetic/horizontal_addition.py b/src/arch/x86/isa/insts/simd128/floating_point/arithmetic/horizontal_addition.py
index 8b307d3da..adf7650b9 100644
--- a/src/arch/x86/isa/insts/simd128/floating_point/arithmetic/horizontal_addition.py
+++ b/src/arch/x86/isa/insts/simd128/floating_point/arithmetic/horizontal_addition.py
@@ -55,5 +55,25 @@
microcode = '''
# HADDPS
-# HADDPD
+
+def macroop HADDPD_XMM_XMM {
+ maddf ufp1, xmmh , xmml, size=8, ext=1
+ maddf xmmh, xmmlm, xmmhm, size=8, ext=1
+ movfp xmml, ufp1
+};
+
+def macroop HADDPD_XMM_M {
+ ldfp ufp1, seg, sib, disp, dataSize=8
+ ldfp ufp2, seg, sib, "DISPLACEMENT+8", dataSize=8
+ maddf xmml, xmmh, xmml, size=8, ext=1
+ maddf xmmh, ufp1, ufp2, size=8, ext=1
+};
+
+def macroop HADDPD_XMM_P {
+ rdip t7
+ ldfp ufp1, seg, riprel, disp, dataSize=8
+ ldfp ufp2, seg, riprel, "DISPLACEMENT+8", dataSize=8
+ maddf xmml, xmmh, xmml, size=8, ext=1
+ maddf xmmh, ufp1, ufp2, size=8, ext=1
+};
'''
diff --git a/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py b/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py
index 1f4044bde..86ac89ade 100644
--- a/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py
+++ b/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py
@@ -168,41 +168,39 @@ def macroop MOVUPD_P_XMM {
};
def macroop MOVHPS_XMM_M {
- ldfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8
+ ldfp xmmh, seg, sib, disp, dataSize=8
};
def macroop MOVHPS_XMM_P {
rdip t7
- ldfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8
+ ldfp xmmh, seg, riprel, disp, dataSize=8
};
def macroop MOVHPS_M_XMM {
- stfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8
+ stfp xmmh, seg, sib, disp, dataSize=8
};
def macroop MOVHPS_P_XMM {
rdip t7
- stfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8
- stfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8
+ stfp xmmh, seg, riprel, disp, dataSize=8
};
def macroop MOVHPD_XMM_M {
- ldfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8
+ ldfp xmmh, seg, sib, disp, dataSize=8
};
def macroop MOVHPD_XMM_P {
rdip t7
- ldfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8
+ ldfp xmmh, seg, riprel, disp, dataSize=8
};
def macroop MOVHPD_M_XMM {
- stfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8
+ stfp xmmh, seg, sib, disp, dataSize=8
};
def macroop MOVHPD_P_XMM {
rdip t7
- stfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8
- stfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8
+ stfp xmmh, seg, riprel, disp, dataSize=8
};
def macroop MOVLPS_XMM_M {
diff --git a/src/arch/x86/isa/insts/simd128/integer/data_transfer/move.py b/src/arch/x86/isa/insts/simd128/integer/data_transfer/move.py
index c34bd42bb..ec80ffe73 100644
--- a/src/arch/x86/isa/insts/simd128/integer/data_transfer/move.py
+++ b/src/arch/x86/isa/insts/simd128/integer/data_transfer/move.py
@@ -87,7 +87,59 @@ def macroop MOVQ2DQ_XMM_MMX {
movfp xmml, mmxm, dataSize=8
lfpimm xmmh, 0
};
+
+def macroop MOVDQA_XMM_XMM {
+ movfp xmml, xmmlm
+ movfp xmmh, xmmhm
+};
+
+def macroop MOVDQA_XMM_M {
+ ldfp xmml, seg, sib, "DISPLACEMENT", dataSize=8
+ ldfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8
+};
+
+def macroop MOVDQA_XMM_P {
+ rdip t7
+ ldfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8
+ ldfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8
+};
+
+def macroop MOVDQA_M_XMM {
+ stfp xmml, seg, sib, "DISPLACEMENT", dataSize=8
+ stfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8
+};
+
+def macroop MOVDQA_P_XMM {
+ rdip t7
+ stfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8
+ stfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8
+};
+
+def macroop MOVDQU_XMM_XMM {
+ movfp xmml, xmmlm
+ movfp xmmh, xmmhm
+};
+
+def macroop MOVDQU_XMM_M {
+ ldfp xmml, seg, sib, "DISPLACEMENT", dataSize=8
+ ldfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8
+};
+
+def macroop MOVDQU_XMM_P {
+ rdip t7
+ ldfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8
+ ldfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8
+};
+
+def macroop MOVDQU_M_XMM {
+ stfp xmml, seg, sib, "DISPLACEMENT", dataSize=8
+ stfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8
+};
+
+def macroop MOVDQU_P_XMM {
+ rdip t7
+ stfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8
+ stfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8
+};
'''
-# MOVDQA
-# MOVDQU
# LDDQU
diff --git a/src/arch/x86/isa/insts/simd128/integer/shift/left_logical_shift.py b/src/arch/x86/isa/insts/simd128/integer/shift/left_logical_shift.py
index 617033bc0..c13c7064c 100644
--- a/src/arch/x86/isa/insts/simd128/integer/shift/left_logical_shift.py
+++ b/src/arch/x86/isa/insts/simd128/integer/shift/left_logical_shift.py
@@ -122,5 +122,43 @@ def macroop PSLLQ_XMM_I {
mslli xmml, xmml, imm, size=8, ext=0
mslli xmmh, xmmh, imm, size=8, ext=0
};
+
+def macroop PSLLDQ_XMM_I {
+
+ limm t2, 8
+ subi t1, t2, imm, flags=(ECF,), dataSize=1
+ br label("pslldq_less_8"), flags=(nCECF,)
+
+ # Greater than 8
+
+ limm t2, 16
+ subi t1, t2, imm, flags=(ECF,), dataSize=1
+ br label("pslldq_less_16"), flags=(nCECF,)
+
+ # Greater than 16
+
+ lfpimm xmml, 0
+ lfpimm xmmh, 0
+ br label("pslldq_end")
+
+pslldq_less_16:
+
+ # Between 8 and 16
+
+ mslli xmmh, xmml, "(IMMEDIATE-8)<<3", size=8, ext=0
+ lfpimm xmml, 0
+ br label("pslldq_end")
+
+pslldq_less_8:
+
+ # Less than 8
+
+ msrli ufp1, xmml, "(8-IMMEDIATE) << 3", size=8, ext=0
+ mslli xmmh, xmmh, "IMMEDIATE << 3", size=8, ext=0
+ mslli xmml, xmml, "IMMEDIATE << 3", size=8, ext=0
+ mor xmmh, xmmh, ufp1
+
+pslldq_end:
+ fault "NoFault"
+};
'''
-# PSLLDQ
diff --git a/src/arch/x86/isa/insts/simd128/integer/shift/right_logical_shift.py b/src/arch/x86/isa/insts/simd128/integer/shift/right_logical_shift.py
index c904eaf50..61efe1a5d 100644
--- a/src/arch/x86/isa/insts/simd128/integer/shift/right_logical_shift.py
+++ b/src/arch/x86/isa/insts/simd128/integer/shift/right_logical_shift.py
@@ -122,5 +122,41 @@ def macroop PSRLQ_XMM_I {
msrli xmml, xmml, imm, size=8, ext=0
msrli xmmh, xmmh, imm, size=8, ext=0
};
+
+def macroop PSRLDQ_XMM_I {
+ limm t2, 8
+ subi t1, t2, imm, flags=(ECF,), dataSize=1
+ br label("psrldq_less_8"), flags=(nCECF,)
+ # Greater than 8
+
+ limm t2, 16
+ subi t1, t2, imm, flags=(ECF,), dataSize=1
+ br label("psrldq_less_16"), flags=(nCECF,)
+
+ # Greater than 16
+
+ lfpimm xmml, 0
+ lfpimm xmmh, 0
+ br label("psrldq_end")
+
+psrldq_less_16:
+
+ # Between 8 and 16
+
+ msrli xmml, xmmh, "(IMMEDIATE-8)<<3", size=8, ext=0
+ lfpimm xmmh, 0
+ br label("psrldq_end")
+
+psrldq_less_8:
+
+ # Less than 8
+
+ mslli ufp1, xmmh, "(8-IMMEDIATE) << 3", size=8, ext=0
+ msrli xmml, xmml, "IMMEDIATE << 3", size=8, ext=0
+ msrli xmmh, xmmh, "IMMEDIATE << 3", size=8, ext=0
+ mor xmml, xmml, ufp1
+
+psrldq_end:
+ fault "NoFault"
+};
'''
-# PSRLDQ
diff --git a/src/arch/x86/isa/insts/system/segmentation.py b/src/arch/x86/isa/insts/system/segmentation.py
index b83fcba95..c97f2f152 100644
--- a/src/arch/x86/isa/insts/system/segmentation.py
+++ b/src/arch/x86/isa/insts/system/segmentation.py
@@ -179,7 +179,8 @@ def macroop LTR_R
wrdh t3, t1, t2
wrdl tr, t1, reg
wrbase tr, t3, dataSize=8
- ori t1, t1, (1 << 9)
+ limm t5, (1 << 9)
+ or t1, t1, t5
st t1, tsg, [8, t4, t0], dataSize=8
};
@@ -195,7 +196,8 @@ def macroop LTR_M
wrdh t3, t1, t2
wrdl tr, t1, t5
wrbase tr, t3, dataSize=8
- ori t1, t1, (1 << 9)
+ limm t5, (1 << 9)
+ or t1, t1, t5
st t1, tsg, [8, t4, t0], dataSize=8
};
@@ -212,7 +214,8 @@ def macroop LTR_P
wrdh t3, t1, t2
wrdl tr, t1, t5
wrbase tr, t3, dataSize=8
- ori t1, t1, (1 << 9)
+ limm t5, (1 << 9)
+ or t1, t1, t5
st t1, tsg, [8, t4, t0], dataSize=8
};
diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa
index 912aa3511..afe1ead59 100644
--- a/src/arch/x86/isa/microops/ldstop.isa
+++ b/src/arch/x86/isa/microops/ldstop.isa
@@ -157,7 +157,7 @@ def template MicroLoadExecute {{
if (fault == NoFault) {
%(code)s;
- } else if (memFlags & Request::PF_EXCLUSIVE) {
+ } else if (memFlags & Request::PREFETCH) {
// For prefetches, ignore any faults/exceptions.
return NoFault;
}
@@ -374,7 +374,7 @@ let {{
if atCPL0:
self.memFlags += " | (CPL0FlagBit << FlagShift)"
if prefetch:
- self.memFlags += " | Request::PF_EXCLUSIVE"
+ self.memFlags += " | Request::PREFETCH"
self.memFlags += " | (machInst.legacy.addr ? " + \
"(AddrSizeFlagBit << FlagShift) : 0)"
diff --git a/src/arch/x86/isa/microops/mediaop.isa b/src/arch/x86/isa/microops/mediaop.isa
index 9c53fa0fb..4052f254d 100644
--- a/src/arch/x86/isa/microops/mediaop.isa
+++ b/src/arch/x86/isa/microops/mediaop.isa
@@ -452,7 +452,7 @@ let {{
if (signBit) {
if (overflow != mask(destBits - srcBits + 1)) {
if (ext & 0x1)
- picked = (1 << (destBits - 1));
+ picked = (ULL(1) << (destBits - 1));
else
picked = 0;
}
@@ -480,7 +480,7 @@ let {{
if (signBit) {
if (overflow != mask(destBits - srcBits + 1)) {
if (ext & 0x1)
- picked = (1 << (destBits - 1));
+ picked = (ULL(1) << (destBits - 1));
else
picked = 0;
}
@@ -642,10 +642,10 @@ let {{
int loIndex = (i + 0) * sizeBits;
uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
int64_t arg1 = arg1Bits |
- (0 - (arg1Bits & (1 << (sizeBits - 1))));
+ (0 - (arg1Bits & (ULL(1) << (sizeBits - 1))));
uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
int64_t arg2 = arg2Bits |
- (0 - (arg2Bits & (1 << (sizeBits - 1))));
+ (0 - (arg2Bits & (ULL(1) << (sizeBits - 1))));
uint64_t resBits;
if (ext & 0x2) {
@@ -680,10 +680,10 @@ let {{
int loIndex = (i + 0) * sizeBits;
uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
int64_t arg1 = arg1Bits |
- (0 - (arg1Bits & (1 << (sizeBits - 1))));
+ (0 - (arg1Bits & (ULL(1) << (sizeBits - 1))));
uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
int64_t arg2 = arg2Bits |
- (0 - (arg2Bits & (1 << (sizeBits - 1))));
+ (0 - (arg2Bits & (ULL(1) << (sizeBits - 1))));
uint64_t resBits;
if (ext & 0x2) {
@@ -957,7 +957,7 @@ let {{
int resSign = bits(resBits, sizeBits - 1);
if ((arg1Sign == arg2Sign) && (arg1Sign != resSign)) {
if (resSign == 0)
- resBits = (1 << (sizeBits - 1));
+ resBits = (ULL(1) << (sizeBits - 1));
else
resBits = mask(sizeBits - 1);
}
@@ -996,7 +996,7 @@ let {{
int resSign = bits(resBits, sizeBits - 1);
if ((arg1Sign == arg2Sign) && (arg1Sign != resSign)) {
if (resSign == 0)
- resBits = (1 << (sizeBits - 1));
+ resBits = (ULL(1) << (sizeBits - 1));
else
resBits = mask(sizeBits - 1);
}
@@ -1032,16 +1032,16 @@ let {{
if (ext & 0x2) {
int64_t arg1 = arg1Bits |
- (0 - (arg1Bits & (1 << (srcBits - 1))));
+ (0 - (arg1Bits & (ULL(1) << (srcBits - 1))));
int64_t arg2 = arg2Bits |
- (0 - (arg2Bits & (1 << (srcBits - 1))));
+ (0 - (arg2Bits & (ULL(1) << (srcBits - 1))));
resBits = (uint64_t)(arg1 * arg2);
} else {
resBits = arg1Bits * arg2Bits;
}
if (ext & 0x4)
- resBits += (1 << (destBits - 1));
+ resBits += (ULL(1) << (destBits - 1));
if (ext & 0x8)
resBits >>= destBits;
@@ -1142,7 +1142,7 @@ let {{
} else {
resBits = (arg1Bits >> shiftAmt);
resBits = resBits |
- (0 - (resBits & (1 << (sizeBits - 1 - shiftAmt))));
+ (0 - (resBits & (ULL(1) << (sizeBits - 1 - shiftAmt))));
}
result = insertBits(result, hiIndex, loIndex, resBits);
@@ -1237,7 +1237,7 @@ let {{
}
if (destSize == 4) {
- argBits = (uint32_t)(float)arg;
+ argBits = (uint32_t)arg;
} else {
argBits = (uint64_t)arg;
}
@@ -1289,7 +1289,8 @@ let {{
int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1;
int srcLoIndex = srcStart + (i + 0) * srcSizeBits;
uint64_t argBits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex);
- int64_t sArg = argBits | (0 - (argBits & (1 << srcHiIndex)));
+
+ int64_t sArg = argBits | (0 - (argBits & (ULL(1) << srcHiIndex)));
double arg = sArg;
if (destSize == 4) {
@@ -1400,10 +1401,10 @@ let {{
int loIndex = (i + 0) * sizeBits;
uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
int64_t arg1 = arg1Bits |
- (0 - (arg1Bits & (1 << (sizeBits - 1))));
+ (0 - (arg1Bits & (ULL(1) << (sizeBits - 1))));
uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
int64_t arg2 = arg2Bits |
- (0 - (arg2Bits & (1 << (sizeBits - 1))));
+ (0 - (arg2Bits & (ULL(1) << (sizeBits - 1))));
uint64_t resBits = 0;
if (((ext & 0x2) == 0 && arg1 == arg2) ||
diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa
index a4cb6f4cc..0b1f9a96a 100644
--- a/src/arch/x86/isa/microops/regop.isa
+++ b/src/arch/x86/isa/microops/regop.isa
@@ -149,12 +149,12 @@ def template MicroRegOpImmDeclare {{
%(class_name)s(ExtMachInst _machInst,
const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
- InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
+ InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest,
uint8_t _dataSize, uint16_t _ext);
%(class_name)s(ExtMachInst _machInst,
const char * instMnem,
- InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
+ InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest,
uint8_t _dataSize, uint16_t _ext);
%(BasicExecDeclare)s
@@ -203,7 +203,7 @@ def template MicroRegOpImmConstructor {{
inline %(class_name)s::%(class_name)s(
ExtMachInst machInst, const char * instMnem,
- InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
+ InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest,
uint8_t _dataSize, uint16_t _ext) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
false, false, false, false,
@@ -216,7 +216,7 @@ def template MicroRegOpImmConstructor {{
inline %(class_name)s::%(class_name)s(
ExtMachInst machInst, const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
- InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
+ InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest,
uint8_t _dataSize, uint16_t _ext) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
isMicro, isDelayed, isFirst, isLast,
@@ -324,11 +324,12 @@ let {{
matcher.sub(src2_name, flag_code),
matcher.sub(src2_name, cond_check),
matcher.sub(src2_name, else_code))
+ imm_name = "%simm8" % match.group("prefix")
self.buildCppClasses(name + "i", Name, suffix + "Imm",
- matcher.sub("imm8", code),
- matcher.sub("imm8", flag_code),
- matcher.sub("imm8", cond_check),
- matcher.sub("imm8", else_code))
+ matcher.sub(imm_name, code),
+ matcher.sub(imm_name, flag_code),
+ matcher.sub(imm_name, cond_check),
+ matcher.sub(imm_name, else_code))
return
# If there's something optional to do with flags, generate
@@ -353,13 +354,16 @@ let {{
matcher = re.compile("(?<!\w)spsrc2(?!\w)")
if matcher.search(allCode):
code = "int64_t spsrc2 = signedPick(SrcReg2, 1, dataSize);" + code
+ matcher = re.compile("(?<!\w)simm8(?!\w)")
+ if matcher.search(allCode):
+ code = "int8_t simm8 = imm8;" + code
base = "X86ISA::RegOp"
# If imm8 shows up in the code, use the immediate templates, if
# not, hopefully the register ones will be correct.
templates = regTemplates
- matcher = re.compile("(?<!\w)imm8(?!\w)")
+ matcher = re.compile("(?<!\w)s?imm8(?!\w)")
if matcher.search(allCode):
base += "Imm"
templates = immTemplates
@@ -521,7 +525,7 @@ let {{
code = '''
ProdLow = psrc1 * op2;
int halfSize = (dataSize * 8) / 2;
- uint64_t shifter = (1ULL << halfSize);
+ uint64_t shifter = (ULL(1) << halfSize);
uint64_t hiResult;
uint64_t psrc1_h = psrc1 / shifter;
uint64_t psrc1_l = psrc1 & mask(halfSize);
@@ -549,7 +553,7 @@ let {{
code = '''
ProdLow = psrc1 * op2;
int halfSize = (dataSize * 8) / 2;
- uint64_t shifter = (1ULL << halfSize);
+ uint64_t shifter = (ULL(1) << halfSize);
uint64_t psrc1_h = psrc1 / shifter;
uint64_t psrc1_l = psrc1 & mask(halfSize);
uint64_t psrc2_h = (op2 / shifter) & mask(halfSize);
diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh
index c2941c769..238b5e683 100644
--- a/src/arch/x86/linux/linux.hh
+++ b/src/arch/x86/linux/linux.hh
@@ -111,6 +111,22 @@ class X86Linux64 : public Linux
uint64_t iov_base; // void *
uint64_t iov_len; // size_t
} tgt_iovec;
+
+ typedef struct {
+ int64_t uptime; /* Seconds since boot */
+ uint64_t loads[3]; /* 1, 5, and 15 minute load averages */
+ uint64_t totalram; /* Total usable main memory size */
+ uint64_t freeram; /* Available memory size */
+ uint64_t sharedram; /* Amount of shared memory */
+ uint64_t bufferram; /* Memory used by buffers */
+ uint64_t totalswap; /* Total swap space size */
+ uint64_t freeswap; /* swap space still available */
+ uint16_t procs; /* Number of current processes */
+ uint64_t totalhigh; /* Total high memory size */
+ uint64_t freehigh; /* Available high memory size */
+ uint64_t mem_unit; /* Memory unit size in bytes */
+ } tgt_sysinfo;
+
};
class X86Linux32 : public Linux
@@ -126,8 +142,8 @@ class X86Linux32 : public Linux
uint32_t st_uid;
uint32_t st_gid;
uint64_t st_rdev;
- int64_t st_size;
uint8_t __pad3[4];
+ int64_t st_size;
uint32_t st_blksize;
uint64_t st_blocks;
uint32_t st_atimeX;
@@ -137,7 +153,7 @@ class X86Linux32 : public Linux
uint32_t st_ctimeX;
uint32_t st_ctime_nsec;
uint64_t st_ino;
- } tgt_stat64;
+ } __attribute__((__packed__)) tgt_stat64;
static OpenFlagTransTable openFlagTable[];
@@ -160,6 +176,23 @@ class X86Linux32 : public Linux
static const int NUM_OPEN_FLAGS;
static const unsigned TGT_MAP_ANONYMOUS = 0x20;
+
+ typedef struct {
+ int32_t uptime; /* Seconds since boot */
+ uint32_t loads[3]; /* 1, 5, and 15 minute load averages */
+ uint32_t totalram; /* Total usable main memory size */
+ uint32_t freeram; /* Available memory size */
+ uint32_t sharedram; /* Amount of shared memory */
+ uint32_t bufferram; /* Memory used by buffers */
+ uint32_t totalswap; /* Total swap space size */
+ uint32_t freeswap; /* swap space still available */
+ uint16_t procs; /* Number of current processes */
+ uint32_t totalhigh; /* Total high memory size */
+ uint32_t freehigh; /* Available high memory size */
+ uint32_t mem_unit; /* Memory unit size in bytes */
+ } tgt_sysinfo;
+
+ static bool mmapGrowsDown() { return true; }
};
#endif
diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc
index 4d7bca95c..6a659108f 100644
--- a/src/arch/x86/linux/syscalls.cc
+++ b/src/arch/x86/linux/syscalls.cc
@@ -68,7 +68,8 @@ static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
+ int index = 0;
+ TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, index));
strcpy(name->sysname, "Linux");
strcpy(name->nodename, "m5.eecs.umich.edu");
@@ -94,8 +95,9 @@ archPrctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
};
//First argument is the code, second is the address
- int code = process->getSyscallArg(tc, 0);
- uint64_t addr = process->getSyscallArg(tc, 1);
+ int index = 0;
+ int code = process->getSyscallArg(tc, index);
+ uint64_t addr = process->getSyscallArg(tc, index);
uint64_t fsBase, gsBase;
TranslatingPort *p = tc->getMemPort();
switch(code)
@@ -159,7 +161,8 @@ setThreadArea32Func(SyscallDesc *desc, int callnum,
assert((maxTLSEntry + 1) * sizeof(uint64_t) <= x86lp->gdtSize());
- TypedBufferArg<UserDesc32> userDesc(process->getSyscallArg(tc, 0));
+ int argIndex = 0;
+ TypedBufferArg<UserDesc32> userDesc(process->getSyscallArg(tc, argIndex));
TypedBufferArg<uint64_t>
gdt(x86lp->gdtStart() + minTLSEntry * sizeof(uint64_t),
numTLSEntries * sizeof(uint64_t));
@@ -232,7 +235,7 @@ SyscallDesc X86_64LinuxProcess::syscallDescs[] = {
/* 1 */ SyscallDesc("write", writeFunc),
/* 2 */ SyscallDesc("open", openFunc<X86Linux64>),
/* 3 */ SyscallDesc("close", closeFunc),
- /* 4 */ SyscallDesc("stat", unimplementedFunc),
+ /* 4 */ SyscallDesc("stat", stat64Func<X86Linux64>),
/* 5 */ SyscallDesc("fstat", fstat64Func<X86Linux64>),
/* 6 */ SyscallDesc("lstat", unimplementedFunc),
/* 7 */ SyscallDesc("poll", unimplementedFunc),
@@ -241,7 +244,7 @@ SyscallDesc X86_64LinuxProcess::syscallDescs[] = {
/* 10 */ SyscallDesc("mprotect", unimplementedFunc),
/* 11 */ SyscallDesc("munmap", munmapFunc),
/* 12 */ SyscallDesc("brk", brkFunc),
- /* 13 */ SyscallDesc("rt_sigaction", unimplementedFunc),
+ /* 13 */ SyscallDesc("rt_sigaction", ignoreFunc),
/* 14 */ SyscallDesc("rt_sigprocmask", unimplementedFunc),
/* 15 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
/* 16 */ SyscallDesc("ioctl", unimplementedFunc),
@@ -304,8 +307,8 @@ SyscallDesc X86_64LinuxProcess::syscallDescs[] = {
/* 73 */ SyscallDesc("flock", unimplementedFunc),
/* 74 */ SyscallDesc("fsync", unimplementedFunc),
/* 75 */ SyscallDesc("fdatasync", unimplementedFunc),
- /* 76 */ SyscallDesc("truncate", unimplementedFunc),
- /* 77 */ SyscallDesc("ftruncate", unimplementedFunc),
+ /* 76 */ SyscallDesc("truncate", truncateFunc),
+ /* 77 */ SyscallDesc("ftruncate", ftruncateFunc),
/* 78 */ SyscallDesc("getdents", unimplementedFunc),
/* 79 */ SyscallDesc("getcwd", unimplementedFunc),
/* 80 */ SyscallDesc("chdir", unimplementedFunc),
@@ -327,7 +330,7 @@ SyscallDesc X86_64LinuxProcess::syscallDescs[] = {
/* 96 */ SyscallDesc("gettimeofday", unimplementedFunc),
/* 97 */ SyscallDesc("getrlimit", unimplementedFunc),
/* 98 */ SyscallDesc("getrusage", unimplementedFunc),
- /* 99 */ SyscallDesc("sysinfo", unimplementedFunc),
+ /* 99 */ SyscallDesc("sysinfo", sysinfoFunc<X86Linux64>),
/* 100 */ SyscallDesc("times", unimplementedFunc),
/* 101 */ SyscallDesc("ptrace", unimplementedFunc),
/* 102 */ SyscallDesc("getuid", getuidFunc),
@@ -429,7 +432,7 @@ SyscallDesc X86_64LinuxProcess::syscallDescs[] = {
/* 198 */ SyscallDesc("lremovexattr", unimplementedFunc),
/* 199 */ SyscallDesc("fremovexattr", unimplementedFunc),
/* 200 */ SyscallDesc("tkill", unimplementedFunc),
- /* 201 */ SyscallDesc("time", unimplementedFunc),
+ /* 201 */ SyscallDesc("time", timeFunc<X86Linux64>),
/* 202 */ SyscallDesc("futex", ignoreFunc),
/* 203 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
/* 204 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
@@ -508,19 +511,19 @@ const int X86_64LinuxProcess::numSyscalls =
SyscallDesc I386LinuxProcess::syscallDescs[] = {
/* 0 */ SyscallDesc("restart_syscall", unimplementedFunc),
- /* 1 */ SyscallDesc("exit", unimplementedFunc),
+ /* 1 */ SyscallDesc("exit", exitFunc),
/* 2 */ SyscallDesc("fork", unimplementedFunc),
- /* 3 */ SyscallDesc("read", unimplementedFunc),
+ /* 3 */ SyscallDesc("read", readFunc),
/* 4 */ SyscallDesc("write", writeFunc),
- /* 5 */ SyscallDesc("open", openFunc<X86Linux64>),
- /* 6 */ SyscallDesc("close", unimplementedFunc),
+ /* 5 */ SyscallDesc("open", openFunc<X86Linux32>),
+ /* 6 */ SyscallDesc("close", closeFunc),
/* 7 */ SyscallDesc("waitpid", unimplementedFunc),
/* 8 */ SyscallDesc("creat", unimplementedFunc),
/* 9 */ SyscallDesc("link", unimplementedFunc),
/* 10 */ SyscallDesc("unlink", unimplementedFunc),
/* 11 */ SyscallDesc("execve", unimplementedFunc),
/* 12 */ SyscallDesc("chdir", unimplementedFunc),
- /* 13 */ SyscallDesc("time", unimplementedFunc),
+ /* 13 */ SyscallDesc("time", timeFunc<X86Linux32>),
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
/* 15 */ SyscallDesc("chmod", unimplementedFunc),
/* 16 */ SyscallDesc("lchown", unimplementedFunc),
@@ -531,7 +534,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = {
/* 21 */ SyscallDesc("mount", unimplementedFunc),
/* 22 */ SyscallDesc("umount", unimplementedFunc),
/* 23 */ SyscallDesc("setuid", unimplementedFunc),
- /* 24 */ SyscallDesc("getuid", unimplementedFunc),
+ /* 24 */ SyscallDesc("getuid", getuidFunc),
/* 25 */ SyscallDesc("stime", unimplementedFunc),
/* 26 */ SyscallDesc("ptrace", unimplementedFunc),
/* 27 */ SyscallDesc("alarm", unimplementedFunc),
@@ -554,10 +557,10 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = {
/* 44 */ SyscallDesc("prof", unimplementedFunc),
/* 45 */ SyscallDesc("brk", brkFunc),
/* 46 */ SyscallDesc("setgid", unimplementedFunc),
- /* 47 */ SyscallDesc("getgid", unimplementedFunc),
+ /* 47 */ SyscallDesc("getgid", getgidFunc),
/* 48 */ SyscallDesc("signal", unimplementedFunc),
- /* 49 */ SyscallDesc("geteuid", unimplementedFunc),
- /* 50 */ SyscallDesc("getegid", unimplementedFunc),
+ /* 49 */ SyscallDesc("geteuid", geteuidFunc),
+ /* 50 */ SyscallDesc("getegid", getegidFunc),
/* 51 */ SyscallDesc("acct", unimplementedFunc),
/* 52 */ SyscallDesc("umount2", unimplementedFunc),
/* 53 */ SyscallDesc("lock", unimplementedFunc),
@@ -598,9 +601,9 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = {
/* 88 */ SyscallDesc("reboot", unimplementedFunc),
/* 89 */ SyscallDesc("readdir", unimplementedFunc),
/* 90 */ SyscallDesc("mmap", unimplementedFunc),
- /* 91 */ SyscallDesc("munmap", unimplementedFunc),
- /* 92 */ SyscallDesc("truncate", unimplementedFunc),
- /* 93 */ SyscallDesc("ftruncate", unimplementedFunc),
+ /* 91 */ SyscallDesc("munmap", munmapFunc),
+ /* 92 */ SyscallDesc("truncate", truncateFunc),
+ /* 93 */ SyscallDesc("ftruncate", ftruncateFunc),
/* 94 */ SyscallDesc("fchmod", unimplementedFunc),
/* 95 */ SyscallDesc("fchown", unimplementedFunc),
/* 96 */ SyscallDesc("getpriority", unimplementedFunc),
@@ -623,7 +626,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = {
/* 113 */ SyscallDesc("vm86old", unimplementedFunc),
/* 114 */ SyscallDesc("wait4", unimplementedFunc),
/* 115 */ SyscallDesc("swapoff", unimplementedFunc),
- /* 116 */ SyscallDesc("sysinfo", unimplementedFunc),
+ /* 116 */ SyscallDesc("sysinfo", sysinfoFunc<X86Linux32>),
/* 117 */ SyscallDesc("ipc", unimplementedFunc),
/* 118 */ SyscallDesc("fsync", unimplementedFunc),
/* 119 */ SyscallDesc("sigreturn", unimplementedFunc),
@@ -681,7 +684,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = {
/* 171 */ SyscallDesc("getresgid", unimplementedFunc),
/* 172 */ SyscallDesc("prctl", unimplementedFunc),
/* 173 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
- /* 174 */ SyscallDesc("rt_sigaction", unimplementedFunc),
+ /* 174 */ SyscallDesc("rt_sigaction", ignoreFunc),
/* 175 */ SyscallDesc("rt_sigprocmask", unimplementedFunc),
/* 176 */ SyscallDesc("rt_sigpending", unimplementedFunc),
/* 177 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
@@ -700,16 +703,16 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = {
/* 190 */ SyscallDesc("vfork", unimplementedFunc),
/* 191 */ SyscallDesc("ugetrlimit", unimplementedFunc),
/* 192 */ SyscallDesc("mmap2", mmapFunc<X86Linux32>),
- /* 193 */ SyscallDesc("truncate64", unimplementedFunc),
- /* 194 */ SyscallDesc("ftruncate64", unimplementedFunc),
- /* 195 */ SyscallDesc("stat64", unimplementedFunc),
+ /* 193 */ SyscallDesc("truncate64", truncate64Func),
+ /* 194 */ SyscallDesc("ftruncate64", ftruncate64Func),
+ /* 195 */ SyscallDesc("stat64", stat64Func<X86Linux32>),
/* 196 */ SyscallDesc("lstat64", unimplementedFunc),
/* 197 */ SyscallDesc("fstat64", fstat64Func<X86Linux32>),
/* 198 */ SyscallDesc("lchown32", unimplementedFunc),
- /* 199 */ SyscallDesc("getuid32", unimplementedFunc),
- /* 200 */ SyscallDesc("getgid32", unimplementedFunc),
- /* 201 */ SyscallDesc("geteuid32", unimplementedFunc),
- /* 202 */ SyscallDesc("getegid32", unimplementedFunc),
+ /* 199 */ SyscallDesc("getuid32", getuidFunc),
+ /* 200 */ SyscallDesc("getgid32", getgidFunc),
+ /* 201 */ SyscallDesc("geteuid32", geteuidFunc),
+ /* 202 */ SyscallDesc("getegid32", getegidFunc),
/* 203 */ SyscallDesc("setreuid32", unimplementedFunc),
/* 204 */ SyscallDesc("setregid32", unimplementedFunc),
/* 205 */ SyscallDesc("getgroups32", unimplementedFunc),
diff --git a/src/arch/x86/predecoder_tables.cc b/src/arch/x86/predecoder_tables.cc
index 5f2b5c421..e8c838dfb 100644
--- a/src/arch/x86/predecoder_tables.cc
+++ b/src/arch/x86/predecoder_tables.cc
@@ -191,7 +191,7 @@ namespace X86ISA
/* 7 */ BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY,
/* 8 */ BY, ZW, BY, BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
/* 9 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
-/* A */ BY, VW, BY, VW, 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 ,
+/* A */ VW, VW, VW, VW, 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 ,
/* B */ BY, BY, BY, BY, BY, BY, BY, BY, VW, VW, VW, VW, VW, VW, VW, VW,
/* C */ BY, BY, WO, 0 , 0 , 0 , BY, ZW, EN, 0 , WO, 0 , 0 , BY, 0 , 0 ,
/* D */ 0 , 0 , 0 , 0 , BY, BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc
index 4082e568c..42ca7b27d 100644
--- a/src/arch/x86/process.cc
+++ b/src/arch/x86/process.cc
@@ -139,6 +139,12 @@ X86_64LiveProcess::X86_64LiveProcess(LiveProcessParams *params,
int _numSyscallDescs) :
X86LiveProcess(params, objFile, _syscallDescs, _numSyscallDescs)
{
+
+ vsyscallPage.base = 0xffffffffff600000ULL;
+ vsyscallPage.size = VMPageSize;
+ vsyscallPage.vtimeOffset = 0x400;
+ vsyscallPage.vgettimeofdayOffset = 0x410;
+
// Set up stack. On X86_64 Linux, stack goes from the top of memory
// downward, less the hole for the kernel address space plus one page
// for undertermined purposes.
@@ -169,7 +175,7 @@ I386LiveProcess::I386LiveProcess(LiveProcessParams *params,
int _numSyscallDescs) :
X86LiveProcess(params, objFile, _syscallDescs, _numSyscallDescs)
{
- _gdtStart = 0x100000000;
+ _gdtStart = ULL(0x100000000);
_gdtSize = VMPageSize;
vsyscallPage.base = 0xffffe000ULL;
@@ -184,7 +190,7 @@ I386LiveProcess::I386LiveProcess(LiveProcessParams *params,
// Set up region for mmaps. This was determined empirically and may not
// always be correct.
- mmap_start = mmap_end = (Addr)0xf7ffd000ULL;
+ mmap_start = mmap_end = (Addr)0xf7ffe000ULL;
}
SyscallDesc*
@@ -205,6 +211,24 @@ X86_64LiveProcess::startup()
argsInit(sizeof(uint64_t), VMPageSize);
+ // Set up the vsyscall page for this process.
+ pTable->allocate(vsyscallPage.base, vsyscallPage.size);
+ uint8_t vtimeBlob[] = {
+ 0x48,0xc7,0xc0,0xc9,0x00,0x00,0x00, // mov $0xc9,%rax
+ 0x0f,0x05, // syscall
+ 0xc3 // retq
+ };
+ initVirtMem->writeBlob(vsyscallPage.base + vsyscallPage.vtimeOffset,
+ vtimeBlob, sizeof(vtimeBlob));
+
+ uint8_t vgettimeofdayBlob[] = {
+ 0x48,0xc7,0xc0,0x60,0x00,0x00,0x00, // mov $0x60,%rax
+ 0x0f,0x05, // syscall
+ 0xc3 // retq
+ };
+ initVirtMem->writeBlob(vsyscallPage.base + vsyscallPage.vgettimeofdayOffset,
+ vgettimeofdayBlob, sizeof(vgettimeofdayBlob));
+
for (int i = 0; i < contextIds.size(); i++) {
ThreadContext * tc = system->getThreadContext(contextIds[i]);
@@ -698,10 +722,10 @@ X86LiveProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn return_value)
}
X86ISA::IntReg
-X86_64LiveProcess::getSyscallArg(ThreadContext *tc, int i)
+X86_64LiveProcess::getSyscallArg(ThreadContext *tc, int &i)
{
assert(i < NumArgumentRegs);
- return tc->readIntReg(ArgumentReg[i]);
+ return tc->readIntReg(ArgumentReg[i++]);
}
void
@@ -712,10 +736,21 @@ X86_64LiveProcess::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val)
}
X86ISA::IntReg
-I386LiveProcess::getSyscallArg(ThreadContext *tc, int i)
+I386LiveProcess::getSyscallArg(ThreadContext *tc, int &i)
{
assert(i < NumArgumentRegs32);
- return tc->readIntReg(ArgumentReg32[i]);
+ return tc->readIntReg(ArgumentReg32[i++]);
+}
+
+X86ISA::IntReg
+I386LiveProcess::getSyscallArg(ThreadContext *tc, int &i, int width)
+{
+ assert(width == 32 || width == 64);
+ assert(i < NumArgumentRegs);
+ uint64_t retVal = tc->readIntReg(ArgumentReg32[i++]) & mask(32);
+ if (width == 64)
+ retVal |= ((uint64_t)tc->readIntReg(ArgumentReg[i++]) << 32);
+ return retVal;
}
void
diff --git a/src/arch/x86/process.hh b/src/arch/x86/process.hh
index cd6d99e66..3ad2abe08 100644
--- a/src/arch/x86/process.hh
+++ b/src/arch/x86/process.hh
@@ -101,11 +101,21 @@ namespace X86ISA
X86_64LiveProcess(LiveProcessParams *params, ObjectFile *objFile,
SyscallDesc *_syscallDescs, int _numSyscallDescs);
+ class VSyscallPage
+ {
+ public:
+ Addr base;
+ Addr size;
+ Addr vtimeOffset;
+ Addr vgettimeofdayOffset;
+ };
+ VSyscallPage vsyscallPage;
+
public:
void argsInit(int intSize, int pageSize);
void startup();
- X86ISA::IntReg getSyscallArg(ThreadContext *tc, int i);
+ X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val);
};
@@ -130,7 +140,8 @@ namespace X86ISA
void startup();
void syscall(int64_t callnum, ThreadContext *tc);
- X86ISA::IntReg getSyscallArg(ThreadContext *tc, int i);
+ X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
+ X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i, int width);
void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val);
};
}
diff --git a/src/arch/x86/system.cc b/src/arch/x86/system.cc
index 1594cc375..31183f2f9 100644
--- a/src/arch/x86/system.cc
+++ b/src/arch/x86/system.cc
@@ -211,7 +211,7 @@ X86System::startup()
numGDTEntries++;
- SegSelector ds;
+ SegSelector ds = 0;
ds.si = numGDTEntries - 1;
tc->setMiscReg(MISCREG_DS, (MiscReg)ds);
diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc
index 5280b9ba8..d7959da2c 100644
--- a/src/arch/x86/tlb.cc
+++ b/src/arch/x86/tlb.cc
@@ -632,12 +632,26 @@ TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation,
Process *p = tc->getProcessPtr();
TlbEntry newEntry;
bool success = p->pTable->lookup(vaddr, newEntry);
- if(!success && mode != Execute) {
+ if (!success && mode != Execute) {
p->checkAndAllocNextPage(vaddr);
success = p->pTable->lookup(vaddr, newEntry);
}
- if(!success) {
- panic("Tried to execute unmapped address %#x.\n", vaddr);
+ if (!success) {
+ if (req->isPrefetch()) {
+ return new PageFault(vaddr, true, mode, true, false);
+ } else {
+ const char *modeStr = "";
+ if (mode == Execute)
+ modeStr = "execute";
+ else if (mode == Read)
+ modeStr = "read";
+ else if (mode == Write)
+ modeStr = "write";
+ else
+ modeStr = "?";
+ panic("Tried to %s unmapped address %#x.\n",
+ modeStr, vaddr);
+ }
} else {
Addr alignedVaddr = p->pTable->pageAlign(vaddr);
DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr,
diff --git a/src/base/bigint.cc b/src/base/bigint.cc
index ce9942c9c..d741e1f7b 100644
--- a/src/base/bigint.cc
+++ b/src/base/bigint.cc
@@ -28,10 +28,10 @@
* Authors: Gabe Black
*/
-#include "base/bigint.hh"
-
#include <iostream>
+#include "base/bigint.hh"
+
using namespace std;
ostream & operator << (ostream & os, const Twin64_t & t)
diff --git a/src/base/bigint.hh b/src/base/bigint.hh
index d60684231..a4e8738d3 100644
--- a/src/base/bigint.hh
+++ b/src/base/bigint.hh
@@ -28,10 +28,11 @@
* Authors: Ali Saidi
*/
-#include "base/misc.hh"
-
#include <iostream>
+#include "base/misc.hh"
+#include "base/types.hh"
+
#ifndef __BASE_BIGINT_HH__
#define __BASE_BIGINT_HH__
// Create a couple of large int types for atomic reads
diff --git a/src/base/cp_annotate.cc b/src/base/cp_annotate.cc
index 0aba2d999..4e138a6dd 100644
--- a/src/base/cp_annotate.cc
+++ b/src/base/cp_annotate.cc
@@ -35,6 +35,7 @@
#include "base/loader/object_file.hh"
#include "base/output.hh"
#include "base/trace.hh"
+#include "config/the_isa.hh"
#include "cpu/thread_context.hh"
#include "sim/arguments.hh"
#include "sim/core.hh"
diff --git a/src/base/cp_annotate.hh b/src/base/cp_annotate.hh
index 05d8129d0..4248c070a 100644
--- a/src/base/cp_annotate.hh
+++ b/src/base/cp_annotate.hh
@@ -41,6 +41,7 @@
#include "base/trace.hh"
#include "base/types.hh"
#include "config/cp_annotate.hh"
+#include "config/the_isa.hh"
#include "sim/serialize.hh"
#include "sim/startup.hh"
#include "sim/system.hh"
diff --git a/src/base/inet.cc b/src/base/inet.cc
index 898a189ef..1a280e993 100644
--- a/src/base/inet.cc
+++ b/src/base/inet.cc
@@ -28,6 +28,7 @@
* Authors: Nathan Binkert
*/
+#include <cstdio>
#include <sstream>
#include <string>
diff --git a/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc
index 15ad88f76..60f0f99b4 100644
--- a/src/base/loader/elf_object.cc
+++ b/src/base/loader/elf_object.cc
@@ -97,6 +97,19 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
arch = ObjectFile::Alpha;
} else if (ehdr.e_machine == EM_ARM) {
arch = ObjectFile::Arm;
+ } else if (ehdr.e_machine == EM_PPC &&
+ ehdr.e_ident[EI_CLASS] == ELFCLASS32) {
+ if (ehdr.e_ident[EI_DATA] == ELFDATA2MSB) {
+ arch = ObjectFile::Power;
+ } else {
+ fatal("The binary you're trying to load is compiled for "
+ "little endian Power.\nM5 only supports big "
+ "endian Power. Please recompile your binary.\n");
+ }
+ } else if (ehdr.e_machine == EM_PPC64) {
+ fatal("The binary you're trying to load is compiled for 64-bit "
+ "Power. M5\n only supports 32-bit Power. Please "
+ "recompile your binary.\n");
} else {
warn("Unknown architecture: %d\n", ehdr.e_machine);
arch = ObjectFile::UnknownArch;
diff --git a/src/base/loader/object_file.hh b/src/base/loader/object_file.hh
index e511451b7..b08f1c633 100644
--- a/src/base/loader/object_file.hh
+++ b/src/base/loader/object_file.hh
@@ -52,7 +52,8 @@ class ObjectFile
Mips,
X86_64,
I386,
- Arm
+ Arm,
+ Power
};
enum OpSys {
diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc
index 6c301b10e..68747b3d1 100644
--- a/src/base/remote_gdb.cc
+++ b/src/base/remote_gdb.cc
@@ -118,6 +118,7 @@
#include <sys/signal.h>
+#include <cstdio>
#include <string>
#include <unistd.h>
@@ -131,9 +132,9 @@
#include "base/remote_gdb.hh"
#include "base/socket.hh"
#include "base/trace.hh"
+#include "config/the_isa.hh"
#include "cpu/thread_context.hh"
#include "cpu/static_inst.hh"
-//#include "mem/physical.hh"
#include "mem/port.hh"
#include "mem/translating_port.hh"
#include "sim/system.hh"
diff --git a/src/base/types.hh b/src/base/types.hh
index 1a6db9fbb..0c10fac64 100644
--- a/src/base/types.hh
+++ b/src/base/types.hh
@@ -55,6 +55,7 @@ typedef int64_t Counter;
* @note using an unsigned breaks the cache.
*/
typedef int64_t Tick;
+typedef uint64_t UTick;
const Tick MaxTick = LL(0x7fffffffffffffff);
diff --git a/src/cpu/BaseCPU.py b/src/cpu/BaseCPU.py
index 4661375ba..ac734e5ac 100644
--- a/src/cpu/BaseCPU.py
+++ b/src/cpu/BaseCPU.py
@@ -26,37 +26,43 @@
#
# Authors: Nathan Binkert
-from MemObject import MemObject
+import sys
+
+from m5.defines import buildEnv
from m5.params import *
from m5.proxy import *
-from m5 import build_env
+
from Bus import Bus
from InstTracer import InstTracer
from ExeTracer import ExeTracer
-import sys
+from MemObject import MemObject
default_tracer = ExeTracer()
-if build_env['TARGET_ISA'] == 'alpha':
+if buildEnv['TARGET_ISA'] == 'alpha':
from AlphaTLB import AlphaDTB, AlphaITB
- if build_env['FULL_SYSTEM']:
+ if buildEnv['FULL_SYSTEM']:
from AlphaInterrupts import AlphaInterrupts
-elif build_env['TARGET_ISA'] == 'sparc':
+elif buildEnv['TARGET_ISA'] == 'sparc':
from SparcTLB import SparcTLB
- if build_env['FULL_SYSTEM']:
+ if buildEnv['FULL_SYSTEM']:
from SparcInterrupts import SparcInterrupts
-elif build_env['TARGET_ISA'] == 'x86':
+elif buildEnv['TARGET_ISA'] == 'x86':
from X86TLB import X86TLB
- if build_env['FULL_SYSTEM']:
+ if buildEnv['FULL_SYSTEM']:
from X86LocalApic import X86LocalApic
-elif build_env['TARGET_ISA'] == 'mips':
+elif buildEnv['TARGET_ISA'] == 'mips':
from MipsTLB import MipsTLB
- if build_env['FULL_SYSTEM']:
+ if buildEnv['FULL_SYSTEM']:
from MipsInterrupts import MipsInterrupts
-elif build_env['TARGET_ISA'] == 'arm':
+elif buildEnv['TARGET_ISA'] == 'arm':
from ArmTLB import ArmTLB
- if build_env['FULL_SYSTEM']:
+ if buildEnv['FULL_SYSTEM']:
from ArmInterrupts import ArmInterrupts
+elif buildEnv['TARGET_ISA'] == 'power':
+ from PowerTLB import PowerTLB
+ if buildEnv['FULL_SYSTEM']:
+ from PowerInterrupts import PowerInterrupts
class BaseCPU(MemObject):
type = 'BaseCPU'
@@ -76,47 +82,54 @@ class BaseCPU(MemObject):
do_statistics_insts = Param.Bool(True,
"enable statistics pseudo instructions")
- if build_env['FULL_SYSTEM']:
+ if buildEnv['FULL_SYSTEM']:
profile = Param.Latency('0ns', "trace the kernel stack")
do_quiesce = Param.Bool(True, "enable quiesce instructions")
else:
workload = VectorParam.Process("processes to run")
- if build_env['TARGET_ISA'] == 'sparc':
+ if buildEnv['TARGET_ISA'] == 'sparc':
dtb = Param.SparcTLB(SparcTLB(), "Data TLB")
itb = Param.SparcTLB(SparcTLB(), "Instruction TLB")
- if build_env['FULL_SYSTEM']:
+ if buildEnv['FULL_SYSTEM']:
interrupts = Param.SparcInterrupts(
SparcInterrupts(), "Interrupt Controller")
- elif build_env['TARGET_ISA'] == 'alpha':
+ elif buildEnv['TARGET_ISA'] == 'alpha':
dtb = Param.AlphaTLB(AlphaDTB(), "Data TLB")
itb = Param.AlphaTLB(AlphaITB(), "Instruction TLB")
- if build_env['FULL_SYSTEM']:
+ if buildEnv['FULL_SYSTEM']:
interrupts = Param.AlphaInterrupts(
AlphaInterrupts(), "Interrupt Controller")
- elif build_env['TARGET_ISA'] == 'x86':
+ elif buildEnv['TARGET_ISA'] == 'x86':
dtb = Param.X86TLB(X86TLB(), "Data TLB")
itb = Param.X86TLB(X86TLB(), "Instruction TLB")
- if build_env['FULL_SYSTEM']:
+ if buildEnv['FULL_SYSTEM']:
_localApic = X86LocalApic(pio_addr=0x2000000000000000)
interrupts = \
Param.X86LocalApic(_localApic, "Interrupt Controller")
- elif build_env['TARGET_ISA'] == 'mips':
+ elif buildEnv['TARGET_ISA'] == 'mips':
dtb = Param.MipsTLB(MipsTLB(), "Data TLB")
itb = Param.MipsTLB(MipsTLB(), "Instruction TLB")
- if build_env['FULL_SYSTEM']:
+ if buildEnv['FULL_SYSTEM']:
interrupts = Param.MipsInterrupts(
MipsInterrupts(), "Interrupt Controller")
- elif build_env['TARGET_ISA'] == 'arm':
+ elif buildEnv['TARGET_ISA'] == 'arm':
UnifiedTLB = Param.Bool(True, "Is this a Unified TLB?")
dtb = Param.ArmTLB(ArmTLB(), "Data TLB")
itb = Param.ArmTLB(ArmTLB(), "Instruction TLB")
- if build_env['FULL_SYSTEM']:
+ if buildEnv['FULL_SYSTEM']:
interrupts = Param.ArmInterrupts(
ArmInterrupts(), "Interrupt Controller")
+ elif buildEnv['TARGET_ISA'] == 'power':
+ UnifiedTLB = Param.Bool(True, "Is this a Unified TLB?")
+ dtb = Param.PowerTLB(PowerTLB(), "Data TLB")
+ itb = Param.PowerTLB(PowerTLB(), "Instruction TLB")
+ if buildEnv['FULL_SYSTEM']:
+ interrupts = Param.PowerInterrupts(
+ PowerInterrupts(), "Interrupt Controller")
else:
print "Don't know what TLB to use for ISA %s" % \
- build_env['TARGET_ISA']
+ buildEnv['TARGET_ISA']
sys.exit(1)
max_insts_all_threads = Param.Counter(0,
@@ -139,7 +152,7 @@ class BaseCPU(MemObject):
tracer = Param.InstTracer(default_tracer, "Instruction tracer")
_mem_ports = []
- if build_env['TARGET_ISA'] == 'x86' and build_env['FULL_SYSTEM']:
+ if buildEnv['TARGET_ISA'] == 'x86' and buildEnv['FULL_SYSTEM']:
_mem_ports = ["itb.walker.port",
"dtb.walker.port",
"interrupts.pio",
@@ -157,7 +170,7 @@ class BaseCPU(MemObject):
self.icache_port = ic.cpu_side
self.dcache_port = dc.cpu_side
self._mem_ports = ['icache.mem_side', 'dcache.mem_side']
- if build_env['TARGET_ISA'] == 'x86' and build_env['FULL_SYSTEM']:
+ if buildEnv['TARGET_ISA'] == 'x86' and buildEnv['FULL_SYSTEM']:
self._mem_ports += ["itb.walker_port", "dtb.walker_port"]
def addTwoLevelCacheHierarchy(self, ic, dc, l2c):
@@ -168,7 +181,7 @@ class BaseCPU(MemObject):
self.l2cache.cpu_side = self.toL2Bus.port
self._mem_ports = ['l2cache.mem_side']
- if build_env['TARGET_ISA'] == 'mips':
+ if buildEnv['TARGET_ISA'] == 'mips':
CP0_IntCtl_IPTI = Param.Unsigned(0,"No Description")
CP0_IntCtl_IPPCI = Param.Unsigned(0,"No Description")
CP0_SrsCtl_HSS = Param.Unsigned(0,"No Description")
diff --git a/src/cpu/CheckerCPU.py b/src/cpu/CheckerCPU.py
index bff9af62d..132254413 100644
--- a/src/cpu/CheckerCPU.py
+++ b/src/cpu/CheckerCPU.py
@@ -27,7 +27,6 @@
# Authors: Nathan Binkert
from m5.params import *
-from m5 import build_env
from BaseCPU import BaseCPU
class CheckerCPU(BaseCPU):
diff --git a/src/cpu/SConscript b/src/cpu/SConscript
index ea79b622c..b89a589c6 100644
--- a/src/cpu/SConscript
+++ b/src/cpu/SConscript
@@ -160,6 +160,7 @@ TraceFlag('DynInst')
TraceFlag('ExecEnable')
TraceFlag('ExecCPSeq')
TraceFlag('ExecEffAddr')
+TraceFlag('ExecFaulting', 'Trace faulting instructions')
TraceFlag('ExecFetchSeq')
TraceFlag('ExecOpClass')
TraceFlag('ExecRegDelta')
@@ -176,6 +177,6 @@ TraceFlag('PCEvent')
TraceFlag('Quiesce')
CompoundFlag('Exec', [ 'ExecEnable', 'ExecTicks', 'ExecOpClass', 'ExecThread',
- 'ExecEffAddr', 'ExecResult', 'ExecSymbol', 'ExecMicro' ])
+ 'ExecEffAddr', 'ExecResult', 'ExecSymbol', 'ExecMicro', 'ExecFaulting' ])
CompoundFlag('ExecNoTicks', [ 'ExecEnable', 'ExecOpClass', 'ExecThread',
- 'ExecEffAddr', 'ExecResult', 'ExecMicro' ])
+ 'ExecEffAddr', 'ExecResult', 'ExecMicro', 'ExecFaulting' ])
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index e4cb79344..556e7ec6f 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -151,7 +151,7 @@ BaseCPU::BaseCPU(Params *p)
*counter = numThreads;
for (ThreadID tid = 0; tid < numThreads; ++tid) {
Event *event = new CountedExitEvent(cause, *counter);
- comInstEventQueue[tid]->schedule(event, p->max_insts_any_thread);
+ comInstEventQueue[tid]->schedule(event, p->max_insts_all_threads);
}
}
diff --git a/src/cpu/base.hh b/src/cpu/base.hh
index 441d9b5dd..bfeec0870 100644
--- a/src/cpu/base.hh
+++ b/src/cpu/base.hh
@@ -38,6 +38,7 @@
#include "arch/microcode_rom.hh"
#include "base/statistics.hh"
#include "config/full_system.hh"
+#include "config/the_isa.hh"
#include "sim/eventq.hh"
#include "sim/insttracer.hh"
#include "mem/mem_object.hh"
diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh
index f4ff88209..31206c81e 100644
--- a/src/cpu/base_dyn_inst.hh
+++ b/src/cpu/base_dyn_inst.hh
@@ -39,6 +39,7 @@
#include "base/fast_alloc.hh"
#include "base/trace.hh"
#include "config/full_system.hh"
+#include "config/the_isa.hh"
#include "cpu/o3/comm.hh"
#include "cpu/exetrace.hh"
#include "cpu/inst_seq.hh"
diff --git a/src/cpu/base_dyn_inst_impl.hh b/src/cpu/base_dyn_inst_impl.hh
index 4ee7d2f2c..70c91ceda 100644
--- a/src/cpu/base_dyn_inst_impl.hh
+++ b/src/cpu/base_dyn_inst_impl.hh
@@ -35,12 +35,11 @@
#include "base/cprintf.hh"
#include "base/trace.hh"
-
-#include "sim/faults.hh"
+#include "config/the_isa.hh"
+#include "cpu/base_dyn_inst.hh"
#include "cpu/exetrace.hh"
#include "mem/request.hh"
-
-#include "cpu/base_dyn_inst.hh"
+#include "sim/faults.hh"
#define NOHASH
#ifndef NOHASH
diff --git a/src/cpu/checker/cpu.cc b/src/cpu/checker/cpu.cc
index 7dacc58ff..16b779e06 100644
--- a/src/cpu/checker/cpu.cc
+++ b/src/cpu/checker/cpu.cc
@@ -326,7 +326,7 @@ CheckerCPU::checkFlags(Request *req)
{
// Remove any dynamic flags that don't have to do with the request itself.
unsigned flags = unverifiedReq->getFlags();
- unsigned mask = LOCKED | PHYSICAL | VPTE | ALTMODE | UNCACHEABLE | NO_FAULT;
+ unsigned mask = LOCKED | PHYSICAL | VPTE | ALTMODE | UNCACHEABLE | PREFETCH;
flags = flags & (mask);
if (flags == req->getFlags()) {
return false;
diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh
index 26571ed68..81f494630 100644
--- a/src/cpu/checker/cpu_impl.hh
+++ b/src/cpu/checker/cpu_impl.hh
@@ -32,6 +32,7 @@
#include <string>
#include "base/refcnt.hh"
+#include "config/the_isa.hh"
#include "cpu/base_dyn_inst.hh"
#include "cpu/checker/cpu.hh"
#include "cpu/simple_thread.hh"
diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh
index d38bd2915..ef7d4c643 100644
--- a/src/cpu/checker/thread_context.hh
+++ b/src/cpu/checker/thread_context.hh
@@ -32,6 +32,7 @@
#define __CPU_CHECKER_THREAD_CONTEXT_HH__
#include "arch/types.hh"
+#include "config/the_isa.hh"
#include "cpu/checker/cpu.hh"
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc
index ea53fb6f5..07be700bb 100644
--- a/src/cpu/exetrace.cc
+++ b/src/cpu/exetrace.cc
@@ -38,6 +38,7 @@
#include "cpu/exetrace.hh"
#include "cpu/static_inst.hh"
#include "cpu/thread_context.hh"
+#include "config/the_isa.hh"
#include "enums/OpClass.hh"
using namespace std;
diff --git a/src/cpu/inorder/InOrderCPU.py b/src/cpu/inorder/InOrderCPU.py
index 9faadc68c..a0b0466a7 100644
--- a/src/cpu/inorder/InOrderCPU.py
+++ b/src/cpu/inorder/InOrderCPU.py
@@ -28,7 +28,6 @@
from m5.params import *
from m5.proxy import *
-from m5 import build_env
from BaseCPU import BaseCPU
class InOrderCPU(BaseCPU):
diff --git a/src/cpu/inorder/SConscript b/src/cpu/inorder/SConscript
index 64f1b5481..82a1028c2 100644
--- a/src/cpu/inorder/SConscript
+++ b/src/cpu/inorder/SConscript
@@ -79,6 +79,7 @@ if 'InOrderCPU' in env['CPU_MODELS']:
Source('resources/mult_div_unit.cc')
Source('resource_pool.cc')
Source('reg_dep_map.cc')
+ Source('thread_state.cc')
Source('thread_context.cc')
Source('cpu.cc')
diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc
index a2367db63..1e3fdc40e 100644
--- a/src/cpu/inorder/cpu.cc
+++ b/src/cpu/inorder/cpu.cc
@@ -33,24 +33,34 @@
#include "arch/utility.hh"
#include "config/full_system.hh"
-#include "cpu/exetrace.hh"
+#include "config/the_isa.hh"
#include "cpu/activity.hh"
-#include "cpu/simple_thread.hh"
-#include "cpu/thread_context.hh"
#include "cpu/base.hh"
-#include "cpu/inorder/inorder_dyn_inst.hh"
-#include "cpu/inorder/thread_context.hh"
-#include "cpu/inorder/thread_state.hh"
+#include "cpu/exetrace.hh"
#include "cpu/inorder/cpu.hh"
-#include "params/InOrderCPU.hh"
-#include "cpu/inorder/pipeline_traits.hh"
#include "cpu/inorder/first_stage.hh"
-#include "cpu/inorder/resources/resource_list.hh"
+#include "cpu/inorder/inorder_dyn_inst.hh"
+#include "cpu/inorder/pipeline_traits.hh"
#include "cpu/inorder/resource_pool.hh"
+#include "cpu/inorder/resources/resource_list.hh"
+#include "cpu/inorder/thread_context.hh"
+#include "cpu/inorder/thread_state.hh"
+#include "cpu/simple_thread.hh"
+#include "cpu/thread_context.hh"
#include "mem/translating_port.hh"
+#include "params/InOrderCPU.hh"
#include "sim/process.hh"
#include "sim/stat_control.hh"
+#if FULL_SYSTEM
+#include "cpu/quiesce_event.hh"
+#include "sim/system.hh"
+#endif
+
+#if THE_ISA == ALPHA_ISA
+#include "arch/alpha/osfpal.hh"
+#endif
+
using namespace std;
using namespace TheISA;
using namespace ThePipeline;
@@ -171,11 +181,16 @@ InOrderCPU::InOrderCPU(Params *params)
timeBuffer(2 , 2),
removeInstsThisCycle(false),
activityRec(params->name, NumStages, 10, params->activity),
+#if FULL_SYSTEM
+ system(params->system),
+ physmem(system->physmem),
+#endif // FULL_SYSTEM
switchCount(0),
deferRegistration(false/*params->deferRegistration*/),
stageTracing(params->stageTracing),
numVirtProcs(1)
{
+ ThreadID active_threads;
cpu_params = params;
resPool = new ResourcePool(this, params);
@@ -183,13 +198,17 @@ InOrderCPU::InOrderCPU(Params *params)
// Resize for Multithreading CPUs
thread.resize(numThreads);
- ThreadID active_threads = params->workload.size();
+#if FULL_SYSTEM
+ active_threads = 1;
+#else
+ active_threads = params->workload.size();
if (active_threads > MaxThreads) {
panic("Workload Size too large. Increase the 'MaxThreads'"
"in your InOrder implementation or "
"edit your workload size.");
}
+#endif
// Bind the fetch & data ports from the resource pool.
fetchPortIdx = resPool->getPortIdx(params->fetchMemPort);
@@ -203,17 +222,23 @@ InOrderCPU::InOrderCPU(Params *params)
}
for (ThreadID tid = 0; tid < numThreads; ++tid) {
+#if FULL_SYSTEM
+ // SMT is not supported in FS mode yet.
+ assert(numThreads == 1);
+ thread[tid] = new Thread(this, 0);
+#else
if (tid < (ThreadID)params->workload.size()) {
DPRINTF(InOrderCPU, "Workload[%i] process is %#x\n",
- tid, this->thread[tid]);
- this->thread[tid] =
+ tid, params->workload[tid]->prog_fname);
+ thread[tid] =
new Thread(this, tid, params->workload[tid]);
} else {
//Allocate Empty thread so M5 can use later
//when scheduling threads to CPU
Process* dummy_proc = params->workload[0];
- this->thread[tid] = new Thread(this, tid, dummy_proc);
+ thread[tid] = new Thread(this, tid, dummy_proc);
}
+#endif
// Setup the TC that will serve as the interface to the threads/CPU.
InOrderThreadContext *tc = new InOrderThreadContext;
@@ -410,7 +435,7 @@ InOrderCPU::tick()
//Tick next_tick = curTick + cycles(1);
//tickEvent.schedule(next_tick);
mainEventQueue.schedule(&tickEvent, nextCycle(curTick + 1));
- DPRINTF(InOrderCPU, "Scheduled CPU for next tick @ %i.\n", nextCycle() + curTick);
+ DPRINTF(InOrderCPU, "Scheduled CPU for next tick @ %i.\n", nextCycle(curTick + 1));
}
}
@@ -447,13 +472,6 @@ InOrderCPU::init()
}
void
-InOrderCPU::readFunctional(Addr addr, uint32_t &buffer)
-{
- tcBase()->getMemPort()->readBlob(addr, (uint8_t*)&buffer, sizeof(uint32_t));
- buffer = gtoh(buffer);
-}
-
-void
InOrderCPU::reset()
{
for (int i = 0; i < numThreads; i++) {
@@ -468,6 +486,61 @@ InOrderCPU::getPort(const std::string &if_name, int idx)
return resPool->getPort(if_name, idx);
}
+#if FULL_SYSTEM
+Fault
+InOrderCPU::hwrei(ThreadID tid)
+{
+ panic("hwrei: Unimplemented");
+
+ return NoFault;
+}
+
+
+bool
+InOrderCPU::simPalCheck(int palFunc, ThreadID tid)
+{
+ panic("simPalCheck: Unimplemented");
+
+ return true;
+}
+
+
+Fault
+InOrderCPU::getInterrupts()
+{
+ // Check if there are any outstanding interrupts
+ return this->interrupts->getInterrupt(this->threadContexts[0]);
+}
+
+
+void
+InOrderCPU::processInterrupts(Fault interrupt)
+{
+ // Check for interrupts here. For now can copy the code that
+ // exists within isa_fullsys_traits.hh. Also assume that thread 0
+ // is the one that handles the interrupts.
+ // @todo: Possibly consolidate the interrupt checking code.
+ // @todo: Allow other threads to handle interrupts.
+
+ assert(interrupt != NoFault);
+ this->interrupts->updateIntrInfo(this->threadContexts[0]);
+
+ DPRINTF(InOrderCPU, "Interrupt %s being handled\n", interrupt->name());
+ this->trap(interrupt, 0);
+}
+
+
+void
+InOrderCPU::updateMemPorts()
+{
+ // Update all ThreadContext's memory ports (Functional/Virtual
+ // Ports)
+ ThreadID size = thread.size();
+ for (ThreadID i = 0; i < size; ++i)
+ thread[i]->connectMemPorts(thread[i]->getTC());
+}
+#endif
+
void
InOrderCPU::trap(Fault fault, ThreadID tid, int delay)
{
@@ -1230,6 +1303,22 @@ InOrderCPU::wakeCPU()
mainEventQueue.schedule(&tickEvent, curTick);
}
+#if FULL_SYSTEM
+
+void
+InOrderCPU::wakeup()
+{
+ if (this->thread[0]->status() != ThreadContext::Suspended)
+ return;
+
+ this->wakeCPU();
+
+ DPRINTF(Quiesce, "Suspended Processor woken\n");
+ this->threadContexts[0]->activate();
+}
+#endif
+
+#if !FULL_SYSTEM
void
InOrderCPU::syscall(int64_t callnum, ThreadID tid)
{
@@ -1251,6 +1340,7 @@ InOrderCPU::syscall(int64_t callnum, ThreadID tid)
// Clear Non-Speculative Block Variable
nonSpecInstActive[tid] = false;
}
+#endif
void
InOrderCPU::prefetch(DynInstPtr inst)
diff --git a/src/cpu/inorder/cpu.hh b/src/cpu/inorder/cpu.hh
index 75d77c818..3320532ba 100644
--- a/src/cpu/inorder/cpu.hh
+++ b/src/cpu/inorder/cpu.hh
@@ -40,10 +40,12 @@
#include "arch/isa_traits.hh"
#include "arch/types.hh"
+#include "arch/registers.hh"
#include "base/statistics.hh"
#include "base/timebuf.hh"
#include "base/types.hh"
#include "config/full_system.hh"
+#include "config/the_isa.hh"
#include "cpu/activity.hh"
#include "cpu/base.hh"
#include "cpu/simple_thread.hh"
@@ -297,6 +299,32 @@ class InOrderCPU : public BaseCPU
/** Get a Memory Port */
Port* getPort(const std::string &if_name, int idx = 0);
+#if FULL_SYSTEM
+ /** HW return from error interrupt. */
+ Fault hwrei(ThreadID tid);
+
+ bool simPalCheck(int palFunc, ThreadID tid);
+
+ /** Returns the Fault for any valid interrupt. */
+ Fault getInterrupts();
+
+ /** Processes any an interrupt fault. */
+ void processInterrupts(Fault interrupt);
+
+ /** Halts the CPU. */
+ void halt() { panic("Halt not implemented!\n"); }
+
+ /** Update the Virt and Phys ports of all ThreadContexts to
+ * reflect change in memory connections. */
+ void updateMemPorts();
+
+ /** Check if this address is a valid instruction address. */
+ bool validInstAddr(Addr addr) { return true; }
+
+ /** Check if this address is a valid data address. */
+ bool validDataAddr(Addr addr) { return true; }
+#endif
+
/** trap() - sets up a trap event on the cpuTraps to handle given fault.
* trapCPU() - Traps to handle given fault
*/
@@ -578,8 +606,6 @@ class InOrderCPU : public BaseCPU
ActivityRecorder activityRec;
public:
- void readFunctional(Addr addr, uint32_t &buffer);
-
/** Number of Active Threads in the CPU */
ThreadID numActiveThreads() { return activeThreads.size(); }
@@ -597,6 +623,10 @@ class InOrderCPU : public BaseCPU
/** Wakes the CPU, rescheduling the CPU if it's not already active. */
void wakeCPU();
+#if FULL_SYSTEM
+ virtual void wakeup();
+#endif
+
/** Gets a free thread id. Use if thread ids change across system. */
ThreadID getFreeTid();
@@ -622,6 +652,14 @@ class InOrderCPU : public BaseCPU
return total;
}
+#if FULL_SYSTEM
+ /** Pointer to the system. */
+ System *system;
+
+ /** Pointer to physical memory. */
+ PhysicalMemory *physmem;
+#endif
+
/** The global sequence number counter. */
InstSeqNum globalSeqNum[ThePipeline::MaxThreads];
diff --git a/src/cpu/inorder/inorder_cpu_builder.cc b/src/cpu/inorder/inorder_cpu_builder.cc
index 5ee7b31db..a19137dd8 100644
--- a/src/cpu/inorder/inorder_cpu_builder.cc
+++ b/src/cpu/inorder/inorder_cpu_builder.cc
@@ -42,12 +42,17 @@
InOrderCPU *
InOrderCPUParams::create()
{
+#if FULL_SYSTEM
+ // Full-system only supports a single thread for the moment.
+ ThreadID actual_num_threads = 1;
+#else
ThreadID actual_num_threads =
(numThreads >= workload.size()) ? numThreads : workload.size();
if (workload.size() == 0) {
fatal("Must specify at least one workload!");
}
+#endif
numThreads = actual_num_threads;
diff --git a/src/cpu/inorder/inorder_dyn_inst.cc b/src/cpu/inorder/inorder_dyn_inst.cc
index a6abb28b2..5ab839615 100644
--- a/src/cpu/inorder/inorder_dyn_inst.cc
+++ b/src/cpu/inorder/inorder_dyn_inst.cc
@@ -34,15 +34,14 @@
#include <string>
#include <sstream>
+#include "arch/faults.hh"
#include "base/cprintf.hh"
#include "base/trace.hh"
-
-#include "arch/faults.hh"
+#include "config/the_isa.hh"
#include "cpu/exetrace.hh"
-#include "mem/request.hh"
-
-#include "cpu/inorder/inorder_dyn_inst.hh"
#include "cpu/inorder/cpu.hh"
+#include "cpu/inorder/inorder_dyn_inst.hh"
+#include "mem/request.hh"
using namespace std;
using namespace TheISA;
@@ -297,11 +296,39 @@ InOrderDynInst::memAccess()
return initiateAcc();
}
+
+#if FULL_SYSTEM
+
+Fault
+InOrderDynInst::hwrei()
+{
+ panic("InOrderDynInst: hwrei: unimplemented\n");
+ return NoFault;
+}
+
+
+void
+InOrderDynInst::trap(Fault fault)
+{
+ this->cpu->trap(fault, this->threadNumber);
+}
+
+
+bool
+InOrderDynInst::simPalCheck(int palFunc)
+{
+#if THE_ISA != ALPHA_ISA
+ panic("simPalCheck called, but PAL only exists in Alpha!\n");
+#endif
+ return this->cpu->simPalCheck(palFunc, this->threadNumber);
+}
+#else
void
InOrderDynInst::syscall(int64_t callnum)
{
cpu->syscall(callnum, this->threadNumber);
}
+#endif
void
InOrderDynInst::prefetch(Addr addr, unsigned flags)
diff --git a/src/cpu/inorder/inorder_dyn_inst.hh b/src/cpu/inorder/inorder_dyn_inst.hh
index e95a6d039..522b4e8d7 100644
--- a/src/cpu/inorder/inorder_dyn_inst.hh
+++ b/src/cpu/inorder/inorder_dyn_inst.hh
@@ -37,25 +37,31 @@
#include <list>
#include <string>
-#include "arch/isa_traits.hh"
#include "arch/faults.hh"
-#include "arch/types.hh"
+#include "arch/isa_traits.hh"
#include "arch/mt.hh"
+#include "arch/types.hh"
#include "base/fast_alloc.hh"
#include "base/trace.hh"
-#include "cpu/inorder/inorder_trace.hh"
+#include "base/types.hh"
#include "config/full_system.hh"
-#include "cpu/thread_context.hh"
+#include "config/the_isa.hh"
#include "cpu/exetrace.hh"
+#include "cpu/inorder/inorder_trace.hh"
+#include "cpu/inorder/pipeline_traits.hh"
+#include "cpu/inorder/resource.hh"
+#include "cpu/inorder/thread_state.hh"
#include "cpu/inst_seq.hh"
#include "cpu/op_class.hh"
#include "cpu/static_inst.hh"
-#include "cpu/inorder/thread_state.hh"
-#include "cpu/inorder/resource.hh"
-#include "cpu/inorder/pipeline_traits.hh"
+#include "cpu/thread_context.hh"
#include "mem/packet.hh"
#include "sim/system.hh"
+#if THE_ISA == ALPHA_ISA
+#include "arch/alpha/ev5.hh"
+#endif
+
/**
* @file
* Defines a dynamic instruction context for a inorder CPU model.
@@ -64,6 +70,7 @@
// Forward declaration.
class StaticInstPtr;
class ResourceRequest;
+class Packet;
class InOrderDynInst : public FastAlloc, public RefCounted
{
@@ -486,7 +493,16 @@ class InOrderDynInst : public FastAlloc, public RefCounted
void setCurResSlot(unsigned slot_num) { curResSlot = slot_num; }
/** Calls a syscall. */
+#if FULL_SYSTEM
+ /** Calls hardware return from error interrupt. */
+ Fault hwrei();
+ /** Traps to handle specified fault. */
+ void trap(Fault fault);
+ bool simPalCheck(int palFunc);
+#else
+ /** Calls a syscall. */
void syscall(int64_t callnum);
+#endif
void prefetch(Addr addr, unsigned flags);
void writeHint(Addr addr, int size, unsigned flags);
Fault copySrcTranslate(Addr src);
diff --git a/src/cpu/inorder/inorder_trace.cc b/src/cpu/inorder/inorder_trace.cc
index f12a1b7a9..90c94a4f5 100644
--- a/src/cpu/inorder/inorder_trace.cc
+++ b/src/cpu/inorder/inorder_trace.cc
@@ -31,6 +31,7 @@
#include <iomanip>
+#include "config/the_isa.hh"
#include "cpu/exetrace.hh"
#include "cpu/inorder/inorder_trace.hh"
#include "cpu/static_inst.hh"
diff --git a/src/cpu/inorder/pipeline_stage.cc b/src/cpu/inorder/pipeline_stage.cc
index 46b1cbad0..dc0378bf3 100644
--- a/src/cpu/inorder/pipeline_stage.cc
+++ b/src/cpu/inorder/pipeline_stage.cc
@@ -30,6 +30,7 @@
*/
#include "base/str.hh"
+#include "config/the_isa.hh"
#include "cpu/inorder/pipeline_stage.hh"
#include "cpu/inorder/resource_pool.hh"
#include "cpu/inorder/cpu.hh"
diff --git a/src/cpu/inorder/reg_dep_map.cc b/src/cpu/inorder/reg_dep_map.cc
index a405b1fb9..51782a588 100644
--- a/src/cpu/inorder/reg_dep_map.cc
+++ b/src/cpu/inorder/reg_dep_map.cc
@@ -30,6 +30,7 @@
*/
#include "arch/isa_traits.hh"
+#include "config/the_isa.hh"
#include "cpu/inorder/pipeline_traits.hh"
#include "cpu/inorder/reg_dep_map.hh"
#include "cpu/inorder/inorder_dyn_inst.hh"
diff --git a/src/cpu/inorder/reg_dep_map.hh b/src/cpu/inorder/reg_dep_map.hh
index ba2a8c8a3..b78e211bb 100644
--- a/src/cpu/inorder/reg_dep_map.hh
+++ b/src/cpu/inorder/reg_dep_map.hh
@@ -36,6 +36,7 @@
#include <vector>
#include "arch/isa_traits.hh"
+#include "config/the_isa.hh"
#include "cpu/inorder/pipeline_traits.hh"
class InOrderCPU;
diff --git a/src/cpu/inorder/resource.hh b/src/cpu/inorder/resource.hh
index 7935e5517..605b7f690 100644
--- a/src/cpu/inorder/resource.hh
+++ b/src/cpu/inorder/resource.hh
@@ -36,6 +36,7 @@
#include <list>
#include <string>
+#include "base/types.hh"
#include "cpu/inst_seq.hh"
#include "cpu/inorder/inorder_dyn_inst.hh"
#include "cpu/inorder/pipeline_traits.hh"
diff --git a/src/cpu/inorder/resources/bpred_unit.cc b/src/cpu/inorder/resources/bpred_unit.cc
index 2ed8586aa..0e8526fa1 100644
--- a/src/cpu/inorder/resources/bpred_unit.cc
+++ b/src/cpu/inorder/resources/bpred_unit.cc
@@ -33,6 +33,7 @@
#include "base/trace.hh"
#include "base/traceflags.hh"
+#include "config/the_isa.hh"
#include "cpu/inorder/resources/bpred_unit.hh"
using namespace std;
diff --git a/src/cpu/inorder/resources/branch_predictor.cc b/src/cpu/inorder/resources/branch_predictor.cc
index 905de0794..ecac5fff0 100644
--- a/src/cpu/inorder/resources/branch_predictor.cc
+++ b/src/cpu/inorder/resources/branch_predictor.cc
@@ -29,6 +29,7 @@
*
*/
+#include "config/the_isa.hh"
#include "cpu/inorder/resources/branch_predictor.hh"
using namespace std;
diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc
index 5677810f6..eb66e10f8 100644
--- a/src/cpu/inorder/resources/cache_unit.cc
+++ b/src/cpu/inorder/resources/cache_unit.cc
@@ -31,10 +31,12 @@
#include <vector>
#include <list>
+
#include "arch/isa_traits.hh"
#include "arch/locked_mem.hh"
#include "arch/utility.hh"
#include "arch/predecoder.hh"
+#include "config/the_isa.hh"
#include "cpu/inorder/resources/cache_unit.hh"
#include "cpu/inorder/pipeline_traits.hh"
#include "cpu/inorder/cpu.hh"
diff --git a/src/cpu/inorder/resources/cache_unit.hh b/src/cpu/inorder/resources/cache_unit.hh
index 8946ad5d3..c467e9771 100644
--- a/src/cpu/inorder/resources/cache_unit.hh
+++ b/src/cpu/inorder/resources/cache_unit.hh
@@ -36,17 +36,17 @@
#include <list>
#include <string>
-#include "arch/tlb.hh"
#include "arch/predecoder.hh"
-#include "cpu/inorder/resource.hh"
+#include "arch/tlb.hh"
+#include "config/the_isa.hh"
#include "cpu/inorder/inorder_dyn_inst.hh"
+#include "cpu/inorder/pipeline_traits.hh"
+#include "cpu/inorder/resource.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "mem/port.hh"
-#include "cpu/inorder/pipeline_traits.hh"
-#include "sim/sim_object.hh"
-
#include "params/InOrderCPU.hh"
+#include "sim/sim_object.hh"
class CacheRequest;
typedef CacheRequest* CacheReqPtr;
diff --git a/src/cpu/inorder/resources/decode_unit.cc b/src/cpu/inorder/resources/decode_unit.cc
index 033c318f2..33f5aba1a 100644
--- a/src/cpu/inorder/resources/decode_unit.cc
+++ b/src/cpu/inorder/resources/decode_unit.cc
@@ -29,6 +29,7 @@
*
*/
+#include "config/the_isa.hh"
#include "cpu/inorder/resources/decode_unit.hh"
using namespace TheISA;
diff --git a/src/cpu/inorder/resources/fetch_seq_unit.cc b/src/cpu/inorder/resources/fetch_seq_unit.cc
index bc809b040..1d0b92075 100644
--- a/src/cpu/inorder/resources/fetch_seq_unit.cc
+++ b/src/cpu/inorder/resources/fetch_seq_unit.cc
@@ -29,6 +29,7 @@
*
*/
+#include "config/the_isa.hh"
#include "cpu/inorder/resources/fetch_seq_unit.hh"
#include "cpu/inorder/resource_pool.hh"
diff --git a/src/cpu/inorder/resources/fetch_seq_unit.hh b/src/cpu/inorder/resources/fetch_seq_unit.hh
index 3e18d47cb..a4495564b 100644
--- a/src/cpu/inorder/resources/fetch_seq_unit.hh
+++ b/src/cpu/inorder/resources/fetch_seq_unit.hh
@@ -36,6 +36,7 @@
#include <list>
#include <string>
+#include "config/the_isa.hh"
#include "cpu/inorder/resource.hh"
#include "cpu/inorder/inorder_dyn_inst.hh"
#include "cpu/inorder/pipeline_traits.hh"
diff --git a/src/cpu/inorder/resources/inst_buffer.cc b/src/cpu/inorder/resources/inst_buffer.cc
index 21df1d053..bb308b0ea 100644
--- a/src/cpu/inorder/resources/inst_buffer.cc
+++ b/src/cpu/inorder/resources/inst_buffer.cc
@@ -31,7 +31,9 @@
#include <vector>
#include <list>
+
#include "arch/isa_traits.hh"
+#include "config/the_isa.hh"
#include "cpu/inorder/pipeline_traits.hh"
#include "cpu/inorder/resources/inst_buffer.hh"
#include "cpu/inorder/cpu.hh"
diff --git a/src/cpu/inorder/resources/inst_buffer_new.cc b/src/cpu/inorder/resources/inst_buffer_new.cc
index cc534ef3e..2e5a9666a 100644
--- a/src/cpu/inorder/resources/inst_buffer_new.cc
+++ b/src/cpu/inorder/resources/inst_buffer_new.cc
@@ -31,7 +31,9 @@
#include <vector>
#include <list>
+
#include "arch/isa_traits.hh"
+#include "config/the_isa.hh"
#include "cpu/inorder/pipeline_traits.hh"
#include "cpu/inorder/resources/inst_buffer.hh"
#include "cpu/inorder/cpu.hh"
diff --git a/src/cpu/inorder/resources/mult_div_unit.cc b/src/cpu/inorder/resources/mult_div_unit.cc
index 7592c0260..e7bd6750f 100644
--- a/src/cpu/inorder/resources/mult_div_unit.cc
+++ b/src/cpu/inorder/resources/mult_div_unit.cc
@@ -91,7 +91,32 @@ MultDivUnit::freeSlot(int slot_idx)
Resource::freeSlot(slot_idx);
}
-
+//@TODO: Should we push this behavior into base-class to generically
+// accomodate all multicyle resources?
+void
+MultDivUnit::requestAgain(DynInstPtr inst, bool &service_request)
+{
+ ResReqPtr mult_div_req = findRequest(inst);
+ assert(mult_div_req);
+
+ service_request = true;
+
+ // Check to see if this instruction is requesting the same command
+ // or a different one
+ if (mult_div_req->cmd != inst->resSched.top()->cmd) {
+ // If different, then update command in the request
+ mult_div_req->cmd = inst->resSched.top()->cmd;
+ DPRINTF(InOrderMDU,
+ "[tid:%i]: [sn:%i]: Updating the command for this instruction\n",
+ inst->readTid(), inst->seqNum);
+ } else {
+ // If same command, just check to see if memory access was completed
+ // but dont try to re-execute
+ DPRINTF(InOrderMDU,
+ "[tid:%i]: [sn:%i]: requesting this resource again\n",
+ inst->readTid(), inst->seqNum);
+ }
+}
int
MultDivUnit::getSlot(DynInstPtr inst)
{
@@ -232,8 +257,13 @@ MultDivUnit::execute(int slot_num)
// counting down the time
{
DPRINTF(InOrderMDU, "End MDU called ...\n");
- if (mult_div_req->getInst()->isExecuted())
+ if (mult_div_req->getInst()->isExecuted()) {
+ DPRINTF(InOrderMDU, "Mult/Div finished.\n");
mult_div_req->done();
+ } else {
+ mult_div_req->setCompleted(false);
+ }
+
}
break;
diff --git a/src/cpu/inorder/resources/mult_div_unit.hh b/src/cpu/inorder/resources/mult_div_unit.hh
index 76180714c..d3dd0260d 100644
--- a/src/cpu/inorder/resources/mult_div_unit.hh
+++ b/src/cpu/inorder/resources/mult_div_unit.hh
@@ -82,6 +82,8 @@ class MultDivUnit : public Resource {
/** Register extra resource stats */
virtual void regStats();
+ void requestAgain(DynInstPtr inst, bool &try_request);
+
protected:
/** Latency & Repeat Rate for Multiply Insts */
unsigned multRepeatRate;
diff --git a/src/cpu/inorder/resources/tlb_unit.cc b/src/cpu/inorder/resources/tlb_unit.cc
index 95bade36a..0410d6b24 100644
--- a/src/cpu/inorder/resources/tlb_unit.cc
+++ b/src/cpu/inorder/resources/tlb_unit.cc
@@ -31,7 +31,9 @@
#include <vector>
#include <list>
+
#include "arch/isa_traits.hh"
+#include "config/the_isa.hh"
#include "cpu/inorder/pipeline_traits.hh"
#include "cpu/inorder/first_stage.hh"
#include "cpu/inorder/resources/tlb_unit.hh"
diff --git a/src/cpu/inorder/resources/tlb_unit.hh b/src/cpu/inorder/resources/tlb_unit.hh
index 1c08bd822..5c62c7751 100644
--- a/src/cpu/inorder/resources/tlb_unit.hh
+++ b/src/cpu/inorder/resources/tlb_unit.hh
@@ -36,6 +36,7 @@
#include <list>
#include <string>
+#include "config/the_isa.hh"
#include "cpu/inorder/resources/inst_buffer.hh"
#include "cpu/inorder/inorder_dyn_inst.hh"
#include "cpu/inorder/pipeline_traits.hh"
diff --git a/src/cpu/inorder/resources/use_def.cc b/src/cpu/inorder/resources/use_def.cc
index 2f1652c08..36392d054 100644
--- a/src/cpu/inorder/resources/use_def.cc
+++ b/src/cpu/inorder/resources/use_def.cc
@@ -31,7 +31,9 @@
#include <vector>
#include <list>
+
#include "arch/isa_traits.hh"
+#include "config/the_isa.hh"
#include "cpu/inorder/pipeline_traits.hh"
#include "cpu/inorder/resources/use_def.hh"
#include "cpu/inorder/cpu.hh"
diff --git a/src/cpu/inorder/thread_context.cc b/src/cpu/inorder/thread_context.cc
index fe1a0faa1..41d16b633 100644
--- a/src/cpu/inorder/thread_context.cc
+++ b/src/cpu/inorder/thread_context.cc
@@ -30,23 +30,77 @@
*/
#include "arch/isa_traits.hh"
+#include "config/the_isa.hh"
#include "cpu/exetrace.hh"
#include "cpu/inorder/thread_context.hh"
using namespace TheISA;
+#if FULL_SYSTEM
+
+VirtualPort *
+InOrderThreadContext::getVirtPort()
+{
+ return thread->getVirtPort();
+}
+
+
+void
+InOrderThreadContext::dumpFuncProfile()
+{
+ thread->dumpFuncProfile();
+}
+
+
+Tick
+InOrderThreadContext::readLastActivate()
+{
+ return thread->lastActivate;
+}
+
+
+Tick
+InOrderThreadContext::readLastSuspend()
+{
+ return thread->lastSuspend;
+}
+
+
+void
+InOrderThreadContext::profileClear()
+{
+ thread->profileClear();
+}
+
+
+void
+InOrderThreadContext::profileSample()
+{
+ thread->profileSample();
+}
+#endif
+
void
InOrderThreadContext::takeOverFrom(ThreadContext *old_context)
{
// some things should already be set up
+ assert(getSystemPtr() == old_context->getSystemPtr());
+#if !FULL_SYSTEM
assert(getProcessPtr() == old_context->getProcessPtr());
+#endif
+
+
// copy over functional state
setStatus(old_context->status());
copyArchRegs(old_context);
+#if !FULL_SYSTEM
thread->funcExeInst = old_context->readFuncExeInst();
+#endif
+
old_context->setStatus(ThreadContext::Halted);
+
thread->inSyscall = false;
thread->trapPending = false;
}
@@ -97,8 +151,8 @@ void
InOrderThreadContext::regStats(const std::string &name)
{
#if FULL_SYSTEM
- thread->kernelStats = new Kernel::Statistics(cpu->system);
- thread->kernelStats->regStats(name + ".kern");
+ //thread->kernelStats = new Kernel::Statistics(cpu->system);
+ //thread->kernelStats->regStats(name + ".kern");
#endif
;
}
@@ -107,22 +161,14 @@ InOrderThreadContext::regStats(const std::string &name)
void
InOrderThreadContext::serialize(std::ostream &os)
{
-#if FULL_SYSTEM
- if (thread->kernelStats)
- thread->kernelStats->serialize(os);
-#endif
- ;
+ panic("serialize unimplemented");
}
void
InOrderThreadContext::unserialize(Checkpoint *cp, const std::string &section)
{
-#if FULL_SYSTEM
- if (thread->kernelStats)
- thread->kernelStats->unserialize(cp, section);
-#endif
- ;
+ panic("unserialize unimplemented");
}
TheISA::MachInst
diff --git a/src/cpu/inorder/thread_context.hh b/src/cpu/inorder/thread_context.hh
index 327f8ac71..820f3077f 100644
--- a/src/cpu/inorder/thread_context.hh
+++ b/src/cpu/inorder/thread_context.hh
@@ -32,6 +32,7 @@
#ifndef __CPU_INORDER_THREAD_CONTEXT_HH__
#define __CPU_INORDER_THREAD_CONTEXT_HH__
+#include "config/the_isa.hh"
#include "cpu/exetrace.hh"
#include "cpu/thread_context.hh"
#include "cpu/inorder/thread_state.hh"
@@ -101,10 +102,48 @@ class InOrderThreadContext : public ThreadContext
virtual void setNextMicroPC(uint64_t val) { };
+#if FULL_SYSTEM
+ /** Returns a pointer to physical memory. */
+ virtual PhysicalMemory *getPhysMemPtr()
+ { assert(0); return 0; /*return cpu->physmem;*/ }
+
+ /** Returns a pointer to this thread's kernel statistics. */
+ virtual TheISA::Kernel::Statistics *getKernelStats()
+ { return thread->kernelStats; }
+
+ virtual FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
+
+ virtual VirtualPort *getVirtPort();
+
+ virtual void connectMemPorts(ThreadContext *tc) { thread->connectMemPorts(tc); }
+
+ /** Dumps the function profiling information.
+ * @todo: Implement.
+ */
+ virtual void dumpFuncProfile();
+
+ /** Reads the last tick that this thread was activated on. */
+ virtual Tick readLastActivate();
+ /** Reads the last tick that this thread was suspended on. */
+ virtual Tick readLastSuspend();
+
+ /** Clears the function profiling information. */
+ virtual void profileClear();
+
+ /** Samples the function profiling information. */
+ virtual void profileSample();
+
+ /** Returns pointer to the quiesce event. */
+ virtual EndQuiesceEvent *getQuiesceEvent()
+ {
+ return this->thread->quiesceEvent;
+ }
+#else
virtual TranslatingPort *getMemPort() { return thread->getMemPort(); }
/** Returns a pointer to this thread's process. */
virtual Process *getProcessPtr() { return thread->getProcessPtr(); }
+#endif
/** Returns this thread's status. */
virtual Status status() const { return thread->status(); }
@@ -232,9 +271,11 @@ class InOrderThreadContext : public ThreadContext
* misspeculating, this is set as false. */
virtual bool misspeculating() { return false; }
+#if !FULL_SYSTEM
/** Executes a syscall in SE mode. */
virtual void syscall(int64_t callnum)
{ return cpu->syscall(callnum, thread->readTid()); }
+#endif
/** Reads the funcExeInst counter. */
virtual Counter readFuncExeInst() { return thread->funcExeInst; }
diff --git a/src/mem/slicc/generator/fileio.hh b/src/cpu/inorder/thread_state.cc
index 81b7306bc..b3a54efb1 100644
--- a/src/mem/slicc/generator/fileio.hh
+++ b/src/cpu/inorder/thread_state.cc
@@ -1,6 +1,5 @@
-
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2007 MIPS Technologies, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,22 +24,24 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * fileio.hh
- *
- * Description:
*
- * $Id: fileio.hh,v 3.2 2003/02/24 20:54:25 xu Exp $
+ * Authors: Korey Sewell
*
- * */
+ */
-#ifndef FILEIO_H
-#define FILEIO_H
+#include "arch/isa_traits.hh"
+#include "cpu/exetrace.hh"
+#include "cpu/inorder/thread_state.hh"
+#include "cpu/inorder/cpu.hh"
-#include "mem/slicc/slicc_global.hh"
+using namespace TheISA;
-void conditionally_write_file(string filename, ostringstream& sstr);
+#if FULL_SYSTEM
+void
+InOrderThreadState::dumpFuncProfile()
+{
+ std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name()));
+ profile->dump(tc, *os);
+}
+#endif
-#endif //FILEIO_H
diff --git a/src/cpu/inorder/thread_state.hh b/src/cpu/inorder/thread_state.hh
index 9b3b39fcb..422df30aa 100644
--- a/src/cpu/inorder/thread_state.hh
+++ b/src/cpu/inorder/thread_state.hh
@@ -33,13 +33,23 @@
#include "arch/faults.hh"
#include "arch/isa_traits.hh"
+#include "base/callback.hh"
+#include "base/output.hh"
#include "cpu/thread_context.hh"
#include "cpu/thread_state.hh"
+#include "sim/sim_exit.hh"
class Event;
+class InOrderCPU;
+
+#if FULL_SYSTEM
+class EndQuiesceEvent;
+class FunctionProfile;
+class ProfileNode;
+#else
class FunctionalMemory;
class Process;
-class InOrderCPU;
+#endif
/**
* Class that has various thread state, such as the status, the
@@ -66,16 +76,28 @@ class InOrderThreadState : public ThreadState {
*/
bool trapPending;
-
+#if FULL_SYSTEM
+ InOrderThreadState(InOrderCPU *_cpu, ThreadID _thread_num)
+ : ThreadState(reinterpret_cast<BaseCPU*>(_cpu), _thread_num),
+ cpu(_cpu), inSyscall(0), trapPending(0)
+ { }
+#else
InOrderThreadState(InOrderCPU *_cpu, ThreadID _thread_num,
Process *_process)
- : ThreadState(reinterpret_cast<BaseCPU*>(_cpu), 0/*_thread_num*/,
+ : ThreadState(reinterpret_cast<BaseCPU*>(_cpu), _thread_num,
_process),
cpu(_cpu), inSyscall(0), trapPending(0)
{ }
+#endif
+#if !FULL_SYSTEM
/** Handles the syscall. */
void syscall(int64_t callnum) { process->syscall(callnum, tc); }
+#endif
+
+#if FULL_SYSTEM
+ void dumpFuncProfile();
+#endif
/** Pointer to the ThreadContext of this thread. */
ThreadContext *tc;
@@ -83,7 +105,7 @@ class InOrderThreadState : public ThreadState {
/** Returns a pointer to the TC of this thread. */
ThreadContext *getTC() { return tc; }
- int readTid() { return 0; }
+ int readTid() { return threadId(); }
/** Pointer to the last graduated instruction in the thread */
//DynInstPtr lastGradInst;
diff --git a/src/cpu/inst_seq.hh b/src/cpu/inst_seq.hh
index 21e04ed25..b5feaf584 100644
--- a/src/cpu/inst_seq.hh
+++ b/src/cpu/inst_seq.hh
@@ -32,6 +32,8 @@
#ifndef __STD_TYPES_HH__
#define __STD_TYPES_HH__
+#include "base/types.hh"
+
// inst sequence type, used to order instructions in the ready list,
// if this rolls over the ready list order temporarily will get messed
// up, but execution will continue and complete correctly
diff --git a/src/cpu/inteltrace.cc b/src/cpu/inteltrace.cc
index 145075dc1..ec51b80e7 100644
--- a/src/cpu/inteltrace.cc
+++ b/src/cpu/inteltrace.cc
@@ -33,6 +33,7 @@
#include <iomanip>
+#include "config/the_isa.hh"
#include "cpu/exetrace.hh"
#include "cpu/inteltrace.hh"
#include "cpu/static_inst.hh"
diff --git a/src/cpu/legiontrace.cc b/src/cpu/legiontrace.cc
index 5face4391..1390d0807 100644
--- a/src/cpu/legiontrace.cc
+++ b/src/cpu/legiontrace.cc
@@ -31,7 +31,7 @@
* Steve Raasch
*/
-#include "arch/isa_specific.hh"
+#include "config/the_isa.hh"
#if THE_ISA != SPARC_ISA
#error Legion tracing only works with SPARC simulations!
#endif
@@ -41,10 +41,12 @@
#error Legion tracing only works in full system!
#endif
-#include <iomanip>
#include <sys/ipc.h>
#include <sys/shm.h>
+#include <cstdio>
+#include <iomanip>
+
#include "arch/sparc/predecoder.hh"
#include "arch/sparc/registers.hh"
#include "arch/sparc/utility.hh"
diff --git a/src/cpu/memtest/MemTest.py b/src/cpu/memtest/MemTest.py
index 629fd4877..8e1b3a8d0 100644
--- a/src/cpu/memtest/MemTest.py
+++ b/src/cpu/memtest/MemTest.py
@@ -29,7 +29,6 @@
from MemObject import MemObject
from m5.params import *
from m5.proxy import *
-from m5 import build_env
class MemTest(MemObject):
type = 'MemTest'
diff --git a/src/cpu/o3/O3CPU.py b/src/cpu/o3/O3CPU.py
index 56e537ad2..3f2210e44 100644
--- a/src/cpu/o3/O3CPU.py
+++ b/src/cpu/o3/O3CPU.py
@@ -26,21 +26,21 @@
#
# Authors: Kevin Lim
+from m5.defines import buildEnv
from m5.params import *
from m5.proxy import *
-from m5 import build_env
from BaseCPU import BaseCPU
from FUPool import *
-if build_env['USE_CHECKER']:
+if buildEnv['USE_CHECKER']:
from O3Checker import O3Checker
class DerivO3CPU(BaseCPU):
type = 'DerivO3CPU'
activity = Param.Unsigned(0, "Initial count")
- if build_env['USE_CHECKER']:
- if not build_env['FULL_SYSTEM']:
+ if buildEnv['USE_CHECKER']:
+ if not buildEnv['FULL_SYSTEM']:
checker = Param.BaseCPU(O3Checker(workload=Parent.workload,
exitOnError=False,
updateOnError=True,
diff --git a/src/cpu/o3/O3Checker.py b/src/cpu/o3/O3Checker.py
index edc6dc9b6..d0c4ce537 100644
--- a/src/cpu/o3/O3Checker.py
+++ b/src/cpu/o3/O3Checker.py
@@ -27,7 +27,6 @@
# Authors: Nathan Binkert
from m5.params import *
-from m5 import build_env
from BaseCPU import BaseCPU
class O3Checker(BaseCPU):
diff --git a/src/cpu/o3/bpred_unit_impl.hh b/src/cpu/o3/bpred_unit_impl.hh
index 1378ac135..ed3471761 100644
--- a/src/cpu/o3/bpred_unit_impl.hh
+++ b/src/cpu/o3/bpred_unit_impl.hh
@@ -28,16 +28,16 @@
* Authors: Kevin Lim
*/
+#include <algorithm>
+
#include "arch/types.hh"
#include "arch/isa_traits.hh"
#include "base/trace.hh"
#include "base/traceflags.hh"
+#include "config/the_isa.hh"
#include "cpu/o3/bpred_unit.hh"
-
#include "params/DerivO3CPU.hh"
-#include <algorithm>
-
template<class Impl>
BPredUnit<Impl>::BPredUnit(DerivO3CPUParams *params)
: _name(params->name + ".BPredUnit"),
diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh
index 7286f1b6f..cb5f23814 100644
--- a/src/cpu/o3/commit_impl.hh
+++ b/src/cpu/o3/commit_impl.hh
@@ -37,6 +37,7 @@
#include "base/loader/symtab.hh"
#include "base/timebuf.hh"
#include "config/full_system.hh"
+#include "config/the_isa.hh"
#include "config/use_checker.hh"
#include "cpu/exetrace.hh"
#include "cpu/o3/commit.hh"
@@ -1075,9 +1076,11 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
commitStatus[tid] = TrapPending;
if (head_inst->traceData) {
- head_inst->traceData->setFetchSeq(head_inst->seqNum);
- head_inst->traceData->setCPSeq(thread[tid]->numInst);
- head_inst->traceData->dump();
+ if (DTRACE(ExecFaulting)) {
+ head_inst->traceData->setFetchSeq(head_inst->seqNum);
+ head_inst->traceData->setCPSeq(thread[tid]->numInst);
+ head_inst->traceData->dump();
+ }
delete head_inst->traceData;
head_inst->traceData = NULL;
}
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index 6722941e4..2a4e0176a 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -30,8 +30,8 @@
*/
#include "config/full_system.hh"
+#include "config/the_isa.hh"
#include "config/use_checker.hh"
-
#include "cpu/activity.hh"
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
@@ -200,7 +200,6 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
globalSeqNum(1),
#if FULL_SYSTEM
system(params->system),
- physmem(system->physmem),
#endif // FULL_SYSTEM
drainCount(0),
deferRegistration(params->defer_registration)
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index 0cc8eab78..2ea918983 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -42,6 +42,7 @@
#include "base/statistics.hh"
#include "base/timebuf.hh"
#include "config/full_system.hh"
+#include "config/the_isa.hh"
#include "config/use_checker.hh"
#include "cpu/activity.hh"
#include "cpu/base.hh"
@@ -668,9 +669,6 @@ class FullO3CPU : public BaseO3CPU
#if FULL_SYSTEM
/** Pointer to the system. */
System *system;
-
- /** Pointer to physical memory. */
- PhysicalMemory *physmem;
#endif
/** Event to call process() on once draining has completed. */
diff --git a/src/cpu/o3/decode_impl.hh b/src/cpu/o3/decode_impl.hh
index 86f87991c..1b76de132 100644
--- a/src/cpu/o3/decode_impl.hh
+++ b/src/cpu/o3/decode_impl.hh
@@ -28,6 +28,7 @@
* Authors: Kevin Lim
*/
+#include "config/the_isa.hh"
#include "cpu/o3/decode.hh"
#include "params/DerivO3CPU.hh"
diff --git a/src/cpu/o3/dyn_inst.hh b/src/cpu/o3/dyn_inst.hh
index 3ef42e91f..e1279f82b 100644
--- a/src/cpu/o3/dyn_inst.hh
+++ b/src/cpu/o3/dyn_inst.hh
@@ -32,6 +32,7 @@
#define __CPU_O3_DYN_INST_HH__
#include "arch/isa_traits.hh"
+#include "config/the_isa.hh"
#include "cpu/base_dyn_inst.hh"
#include "cpu/inst_seq.hh"
#include "cpu/o3/cpu.hh"
diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh
index 9cbc50899..425c34428 100644
--- a/src/cpu/o3/fetch.hh
+++ b/src/cpu/o3/fetch.hh
@@ -36,6 +36,7 @@
#include "arch/predecoder.hh"
#include "base/statistics.hh"
#include "base/timebuf.hh"
+#include "config/the_isa.hh"
#include "cpu/pc_event.hh"
#include "mem/packet.hh"
#include "mem/port.hh"
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index 3781113bd..e6815ef8a 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -35,6 +35,7 @@
#include "arch/isa_traits.hh"
#include "arch/utility.hh"
#include "base/types.hh"
+#include "config/the_isa.hh"
#include "config/use_checker.hh"
#include "cpu/checker/cpu.hh"
#include "cpu/exetrace.hh"
@@ -1263,6 +1264,8 @@ DefaultFetch<Impl>::fetch(bool &status_change)
toDecode->insts[numInst] = instruction;
toDecode->size++;
+ wroteToTimeBuffer = true;
+
DPRINTF(Fetch, "[tid:%i]: Blocked, need to handle the trap.\n",tid);
fetchStatus[tid] = TrapPending;
diff --git a/src/cpu/o3/free_list.hh b/src/cpu/o3/free_list.hh
index e28c4910e..96289f641 100644
--- a/src/cpu/o3/free_list.hh
+++ b/src/cpu/o3/free_list.hh
@@ -38,6 +38,7 @@
#include "base/misc.hh"
#include "base/trace.hh"
#include "base/traceflags.hh"
+#include "config/the_isa.hh"
#include "cpu/o3/comm.hh"
/**
diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh
index ba29df196..751a26afd 100644
--- a/src/cpu/o3/iew_impl.hh
+++ b/src/cpu/o3/iew_impl.hh
@@ -35,6 +35,7 @@
#include <queue>
#include "base/timebuf.hh"
+#include "config/the_isa.hh"
#include "cpu/o3/fu_pool.hh"
#include "cpu/o3/iew.hh"
#include "params/DerivO3CPU.hh"
diff --git a/src/cpu/o3/impl.hh b/src/cpu/o3/impl.hh
index 4b29b4daa..ffccd4a84 100644
--- a/src/cpu/o3/impl.hh
+++ b/src/cpu/o3/impl.hh
@@ -32,7 +32,7 @@
#define __CPU_O3_IMPL_HH__
#include "arch/isa_traits.hh"
-
+#include "config/the_isa.hh"
#include "cpu/o3/cpu_policy.hh"
diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh
index a917caef3..6ff36d929 100644
--- a/src/cpu/o3/lsq_unit.hh
+++ b/src/cpu/o3/lsq_unit.hh
@@ -40,6 +40,7 @@
#include "arch/faults.hh"
#include "arch/locked_mem.hh"
#include "config/full_system.hh"
+#include "config/the_isa.hh"
#include "base/fast_alloc.hh"
#include "base/hashmap.hh"
#include "cpu/inst_seq.hh"
diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh
index edc8c9b3f..9ee1de45a 100644
--- a/src/cpu/o3/lsq_unit_impl.hh
+++ b/src/cpu/o3/lsq_unit_impl.hh
@@ -30,8 +30,8 @@
*/
#include "arch/locked_mem.hh"
+#include "config/the_isa.hh"
#include "config/use_checker.hh"
-
#include "cpu/o3/lsq.hh"
#include "cpu/o3/lsq_unit.hh"
#include "base/str.hh"
diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh
index d6beecdc5..e252fa362 100644
--- a/src/cpu/o3/regfile.hh
+++ b/src/cpu/o3/regfile.hh
@@ -32,18 +32,19 @@
#ifndef __CPU_O3_REGFILE_HH__
#define __CPU_O3_REGFILE_HH__
+#include <vector>
+
#include "arch/isa_traits.hh"
#include "arch/types.hh"
#include "base/trace.hh"
#include "config/full_system.hh"
+#include "config/the_isa.hh"
#include "cpu/o3/comm.hh"
#if FULL_SYSTEM
#include "arch/kernel_stats.hh"
#endif
-#include <vector>
-
/**
* Simple physical register file class.
* Right now this is specific to Alpha until we decide if/how to make things
diff --git a/src/cpu/o3/rename.hh b/src/cpu/o3/rename.hh
index 734b63105..8c21dda0a 100644
--- a/src/cpu/o3/rename.hh
+++ b/src/cpu/o3/rename.hh
@@ -35,6 +35,7 @@
#include "base/statistics.hh"
#include "base/timebuf.hh"
+#include "config/the_isa.hh"
class DerivO3CPUParams;
diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh
index e4cc2674b..ce206435c 100644
--- a/src/cpu/o3/rename_impl.hh
+++ b/src/cpu/o3/rename_impl.hh
@@ -34,6 +34,7 @@
#include "arch/isa_traits.hh"
#include "arch/registers.hh"
#include "config/full_system.hh"
+#include "config/the_isa.hh"
#include "cpu/o3/rename.hh"
#include "params/DerivO3CPU.hh"
diff --git a/src/cpu/o3/rename_map.hh b/src/cpu/o3/rename_map.hh
index 896c66f3e..51d8db4d8 100644
--- a/src/cpu/o3/rename_map.hh
+++ b/src/cpu/o3/rename_map.hh
@@ -39,8 +39,9 @@
#include <utility>
#include <vector>
-#include "cpu/o3/free_list.hh"
#include "arch/types.hh"
+#include "config/the_isa.hh"
+#include "cpu/o3/free_list.hh"
class SimpleRenameMap
{
diff --git a/src/cpu/o3/rob.hh b/src/cpu/o3/rob.hh
index 657bc8d06..bdea07d1a 100644
--- a/src/cpu/o3/rob.hh
+++ b/src/cpu/o3/rob.hh
@@ -36,6 +36,8 @@
#include <utility>
#include <vector>
+#include "config/the_isa.hh"
+
/**
* ROB class. The ROB is largely what drives squashing.
*/
diff --git a/src/cpu/o3/scoreboard.cc b/src/cpu/o3/scoreboard.cc
index e7f8b7949..ae1e13717 100644
--- a/src/cpu/o3/scoreboard.cc
+++ b/src/cpu/o3/scoreboard.cc
@@ -29,7 +29,7 @@
* Kevin Lim
*/
-#include "arch/isa_specific.hh"
+#include "config/the_isa.hh"
#include "cpu/o3/scoreboard.hh"
Scoreboard::Scoreboard(unsigned activeThreads,
diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh
index ed5c6ac20..78b266014 100755
--- a/src/cpu/o3/thread_context.hh
+++ b/src/cpu/o3/thread_context.hh
@@ -31,6 +31,7 @@
#ifndef __CPU_O3_THREAD_CONTEXT_HH__
#define __CPU_O3_THREAD_CONTEXT_HH__
+#include "config/the_isa.hh"
#include "cpu/thread_context.hh"
#include "cpu/o3/isa_specific.hh"
@@ -90,9 +91,6 @@ class O3ThreadContext : public ThreadContext
virtual System *getSystemPtr() { return cpu->system; }
#if FULL_SYSTEM
- /** Returns a pointer to physical memory. */
- virtual PhysicalMemory *getPhysMemPtr() { return cpu->physmem; }
-
/** Returns a pointer to this thread's kernel statistics. */
virtual TheISA::Kernel::Statistics *getKernelStats()
{ return thread->kernelStats; }
diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh
index e631c9244..940d460ce 100755
--- a/src/cpu/o3/thread_context_impl.hh
+++ b/src/cpu/o3/thread_context_impl.hh
@@ -30,6 +30,7 @@
*/
#include "arch/registers.hh"
+#include "config/the_isa.hh"
#include "cpu/o3/thread_context.hh"
#include "cpu/quiesce_event.hh"
diff --git a/src/cpu/ozone/OzoneCPU.py b/src/cpu/ozone/OzoneCPU.py
index 37386898d..2c7b8475f 100644
--- a/src/cpu/ozone/OzoneCPU.py
+++ b/src/cpu/ozone/OzoneCPU.py
@@ -26,11 +26,11 @@
#
# Authors: Kevin Lim
+from m5.defines import buildEnv
from m5.params import *
-from m5 import build_env
from BaseCPU import BaseCPU
-if build_env['USE_CHECKER']:
+if buildEnv['USE_CHECKER']:
from OzoneChecker import OzoneChecker
class DerivOzoneCPU(BaseCPU):
@@ -38,7 +38,7 @@ class DerivOzoneCPU(BaseCPU):
numThreads = Param.Unsigned("number of HW thread contexts")
- if build_env['USE_CHECKER']:
+ if buildEnv['USE_CHECKER']:
checker = Param.BaseCPU("Checker CPU")
icache_port = Port("Instruction Port")
diff --git a/src/cpu/ozone/OzoneChecker.py b/src/cpu/ozone/OzoneChecker.py
index bfa39ead9..bbe46db18 100644
--- a/src/cpu/ozone/OzoneChecker.py
+++ b/src/cpu/ozone/OzoneChecker.py
@@ -27,7 +27,6 @@
# Authors: Nathan Binkert
from m5.params import *
-from m5 import build_env
from BaseCPU import BaseCPU
class OzoneChecker(BaseCPU):
diff --git a/src/cpu/ozone/SimpleOzoneCPU.py b/src/cpu/ozone/SimpleOzoneCPU.py
index 93603092b..d4620cd8e 100644
--- a/src/cpu/ozone/SimpleOzoneCPU.py
+++ b/src/cpu/ozone/SimpleOzoneCPU.py
@@ -26,8 +26,8 @@
#
# Authors: Kevin Lim
+from m5.defines import buildEnv
from m5.params import *
-from m5 import build_env
from BaseCPU import BaseCPU
class SimpleOzoneCPU(BaseCPU):
@@ -35,7 +35,7 @@ class SimpleOzoneCPU(BaseCPU):
numThreads = Param.Unsigned("number of HW thread contexts")
- if not build_env['FULL_SYSTEM']:
+ if not buildEnv['FULL_SYSTEM']:
mem = Param.FunctionalMemory(NULL, "memory")
width = Param.Unsigned("Width")
diff --git a/src/cpu/ozone/cpu.hh b/src/cpu/ozone/cpu.hh
index 5e36332af..a16986c99 100644
--- a/src/cpu/ozone/cpu.hh
+++ b/src/cpu/ozone/cpu.hh
@@ -36,6 +36,7 @@
#include "base/statistics.hh"
#include "base/timebuf.hh"
#include "config/full_system.hh"
+#include "config/the_isa.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "cpu/inst_seq.hh"
diff --git a/src/cpu/ozone/cpu_impl.hh b/src/cpu/ozone/cpu_impl.hh
index f86b882d1..c09dd9046 100644
--- a/src/cpu/ozone/cpu_impl.hh
+++ b/src/cpu/ozone/cpu_impl.hh
@@ -34,6 +34,7 @@
#include "arch/isa_traits.hh" // For MachInst
#include "base/trace.hh"
+#include "config/the_isa.hh"
#include "cpu/base.hh"
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
diff --git a/src/cpu/ozone/dyn_inst.hh b/src/cpu/ozone/dyn_inst.hh
index a39f383ba..cca72ef18 100644
--- a/src/cpu/ozone/dyn_inst.hh
+++ b/src/cpu/ozone/dyn_inst.hh
@@ -34,6 +34,7 @@
#include "arch/isa_traits.hh"
#include "arch/types.hh"
#include "config/full_system.hh"
+#include "config/the_isa.hh"
#include "cpu/base_dyn_inst.hh"
#include "cpu/inst_seq.hh"
#include "cpu/ozone/cpu.hh" // MUST include this
diff --git a/src/cpu/ozone/dyn_inst_impl.hh b/src/cpu/ozone/dyn_inst_impl.hh
index 8519917f5..bfefb9428 100644
--- a/src/cpu/ozone/dyn_inst_impl.hh
+++ b/src/cpu/ozone/dyn_inst_impl.hh
@@ -30,6 +30,7 @@
#include "sim/faults.hh"
#include "config/full_system.hh"
+#include "config/the_isa.hh"
#include "cpu/ozone/dyn_inst.hh"
#if FULL_SYSTEM
diff --git a/src/cpu/ozone/front_end.hh b/src/cpu/ozone/front_end.hh
index 38fc89e3f..3809db00d 100644
--- a/src/cpu/ozone/front_end.hh
+++ b/src/cpu/ozone/front_end.hh
@@ -35,6 +35,7 @@
#include "arch/utility.hh"
#include "base/timebuf.hh"
+#include "config/the_isa.hh"
#include "cpu/inst_seq.hh"
#include "cpu/o3/bpred_unit.hh"
#include "cpu/ozone/rename_table.hh"
diff --git a/src/cpu/ozone/front_end_impl.hh b/src/cpu/ozone/front_end_impl.hh
index 516823b47..884136927 100644
--- a/src/cpu/ozone/front_end_impl.hh
+++ b/src/cpu/ozone/front_end_impl.hh
@@ -28,12 +28,12 @@
* Authors: Kevin Lim
*/
-#include "config/use_checker.hh"
-
#include "sim/faults.hh"
#include "arch/isa_traits.hh"
#include "arch/utility.hh"
#include "base/statistics.hh"
+#include "config/the_isa.hh"
+#include "config/use_checker.hh"
#include "cpu/thread_context.hh"
#include "cpu/exetrace.hh"
#include "cpu/ozone/front_end.hh"
diff --git a/src/cpu/ozone/inorder_back_end_impl.hh b/src/cpu/ozone/inorder_back_end_impl.hh
index 798b628d6..2d4d225c7 100644
--- a/src/cpu/ozone/inorder_back_end_impl.hh
+++ b/src/cpu/ozone/inorder_back_end_impl.hh
@@ -30,6 +30,7 @@
#include "sim/faults.hh"
#include "arch/types.hh"
+#include "config/the_isa.hh"
#include "cpu/ozone/inorder_back_end.hh"
#include "cpu/ozone/thread_state.hh"
diff --git a/src/cpu/ozone/lsq_unit.hh b/src/cpu/ozone/lsq_unit.hh
index 47be245e5..d8e402b65 100644
--- a/src/cpu/ozone/lsq_unit.hh
+++ b/src/cpu/ozone/lsq_unit.hh
@@ -38,6 +38,7 @@
#include "arch/faults.hh"
#include "arch/types.hh"
#include "config/full_system.hh"
+#include "config/the_isa.hh"
#include "base/hashmap.hh"
#include "cpu/inst_seq.hh"
#include "mem/mem_interface.hh"
diff --git a/src/cpu/ozone/lsq_unit_impl.hh b/src/cpu/ozone/lsq_unit_impl.hh
index 833aa0581..dd44adf6e 100644
--- a/src/cpu/ozone/lsq_unit_impl.hh
+++ b/src/cpu/ozone/lsq_unit_impl.hh
@@ -30,6 +30,7 @@
#include "arch/faults.hh"
#include "base/str.hh"
+#include "config/the_isa.hh"
#include "cpu/ozone/lsq_unit.hh"
template <class Impl>
diff --git a/src/cpu/ozone/lw_back_end_impl.hh b/src/cpu/ozone/lw_back_end_impl.hh
index 86d4531a0..cbc386cb0 100644
--- a/src/cpu/ozone/lw_back_end_impl.hh
+++ b/src/cpu/ozone/lw_back_end_impl.hh
@@ -28,8 +28,8 @@
* Authors: Kevin Lim
*/
+#include "config/the_isa.hh"
#include "config/use_checker.hh"
-
#include "cpu/ozone/lw_back_end.hh"
#include "cpu/op_class.hh"
diff --git a/src/cpu/ozone/lw_lsq.hh b/src/cpu/ozone/lw_lsq.hh
index 6e9bb77af..ee0312969 100644
--- a/src/cpu/ozone/lw_lsq.hh
+++ b/src/cpu/ozone/lw_lsq.hh
@@ -39,6 +39,7 @@
#include "arch/faults.hh"
#include "arch/types.hh"
#include "config/full_system.hh"
+#include "config/the_isa.hh"
#include "base/fast_alloc.hh"
#include "base/hashmap.hh"
#include "cpu/inst_seq.hh"
diff --git a/src/cpu/ozone/lw_lsq_impl.hh b/src/cpu/ozone/lw_lsq_impl.hh
index 4d290a1e9..c714c5d38 100644
--- a/src/cpu/ozone/lw_lsq_impl.hh
+++ b/src/cpu/ozone/lw_lsq_impl.hh
@@ -28,10 +28,10 @@
* Authors: Kevin Lim
*/
-#include "config/use_checker.hh"
-
#include "arch/faults.hh"
#include "base/str.hh"
+#include "config/the_isa.hh"
+#include "config/use_checker.hh"
#include "cpu/ozone/lw_lsq.hh"
#include "cpu/checker/cpu.hh"
diff --git a/src/cpu/ozone/rename_table.hh b/src/cpu/ozone/rename_table.hh
index 0b67d9635..9a5579158 100644
--- a/src/cpu/ozone/rename_table.hh
+++ b/src/cpu/ozone/rename_table.hh
@@ -32,6 +32,7 @@
#define __CPU_OZONE_RENAME_TABLE_HH__
#include "arch/isa_traits.hh"
+#include "config/the_isa.hh"
/** Rename table that holds the rename of each architectural register to
* producing DynInst. Needs to support copying from one table to another.
diff --git a/src/cpu/ozone/rename_table_impl.hh b/src/cpu/ozone/rename_table_impl.hh
index 67bab7337..e8071e2b3 100644
--- a/src/cpu/ozone/rename_table_impl.hh
+++ b/src/cpu/ozone/rename_table_impl.hh
@@ -29,6 +29,8 @@
*/
#include <cstdlib> // Not really sure what to include to get NULL
+
+#include "config/the_isa.hh"
#include "cpu/ozone/rename_table.hh"
template <class Impl>
diff --git a/src/cpu/ozone/simple_params.hh b/src/cpu/ozone/simple_params.hh
index 7687fdf60..b241dea73 100644
--- a/src/cpu/ozone/simple_params.hh
+++ b/src/cpu/ozone/simple_params.hh
@@ -31,6 +31,7 @@
#ifndef __CPU_OZONE_SIMPLE_PARAMS_HH__
#define __CPU_OZONE_SIMPLE_PARAMS_HH__
+#include "config/the_isa.hh"
#include "cpu/ozone/cpu.hh"
//Forward declarations
diff --git a/src/cpu/ozone/thread_state.hh b/src/cpu/ozone/thread_state.hh
index 971fba886..638b9d86c 100644
--- a/src/cpu/ozone/thread_state.hh
+++ b/src/cpu/ozone/thread_state.hh
@@ -31,13 +31,14 @@
#ifndef __CPU_OZONE_THREAD_STATE_HH__
#define __CPU_OZONE_THREAD_STATE_HH__
-#include "sim/faults.hh"
-#include "arch/types.hh"
#include "arch/regfile.hh"
+#include "arch/types.hh"
#include "base/callback.hh"
#include "base/output.hh"
+#include "config/the_isa.hh"
#include "cpu/thread_context.hh"
#include "cpu/thread_state.hh"
+#include "sim/faults.hh"
#include "sim/process.hh"
#include "sim/sim_exit.hh"
diff --git a/src/cpu/profile.hh b/src/cpu/profile.hh
index 9606ed24d..dd856b5a7 100644
--- a/src/cpu/profile.hh
+++ b/src/cpu/profile.hh
@@ -34,6 +34,7 @@
#include <map>
#include "arch/stacktrace.hh"
+#include "config/the_isa.hh"
#include "cpu/static_inst.hh"
#include "base/types.hh"
diff --git a/src/cpu/simple/AtomicSimpleCPU.py b/src/cpu/simple/AtomicSimpleCPU.py
index b7174bb43..3d72f4098 100644
--- a/src/cpu/simple/AtomicSimpleCPU.py
+++ b/src/cpu/simple/AtomicSimpleCPU.py
@@ -27,7 +27,6 @@
# Authors: Nathan Binkert
from m5.params import *
-from m5 import build_env
from BaseSimpleCPU import BaseSimpleCPU
class AtomicSimpleCPU(BaseSimpleCPU):
diff --git a/src/cpu/simple/TimingSimpleCPU.py b/src/cpu/simple/TimingSimpleCPU.py
index ce6839241..6b83c41aa 100644
--- a/src/cpu/simple/TimingSimpleCPU.py
+++ b/src/cpu/simple/TimingSimpleCPU.py
@@ -27,7 +27,6 @@
# Authors: Nathan Binkert
from m5.params import *
-from m5 import build_env
from BaseSimpleCPU import BaseSimpleCPU
class TimingSimpleCPU(BaseSimpleCPU):
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index 83da618f8..05b4ca3e2 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -32,6 +32,7 @@
#include "arch/mmaped_ipr.hh"
#include "arch/utility.hh"
#include "base/bigint.hh"
+#include "config/the_isa.hh"
#include "cpu/exetrace.hh"
#include "cpu/simple/atomic.hh"
#include "mem/packet.hh"
@@ -170,6 +171,9 @@ AtomicSimpleCPU::AtomicSimpleCPU(AtomicSimpleCPUParams *p)
AtomicSimpleCPU::~AtomicSimpleCPU()
{
+ if (tickEvent.scheduled()) {
+ deschedule(tickEvent);
+ }
}
void
@@ -352,8 +356,14 @@ AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags)
recordEvent("Uncached Read");
//If there's a fault, return it
- if (fault != NoFault)
- return fault;
+ if (fault != NoFault) {
+ if (req->isPrefetch()) {
+ return NoFault;
+ } else {
+ return fault;
+ }
+ }
+
//If we don't need to access a second cache line, stop now.
if (secondAddr <= addr)
{
@@ -530,7 +540,11 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
assert(locked);
locked = false;
}
- return fault;
+ if (fault != NoFault && req->isPrefetch()) {
+ return NoFault;
+ } else {
+ return fault;
+ }
}
/*
diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc
index 732bb637b..0104e1b1f 100644
--- a/src/cpu/simple/base.cc
+++ b/src/cpu/simple/base.cc
@@ -40,6 +40,7 @@
#include "base/stats/events.hh"
#include "base/trace.hh"
#include "base/types.hh"
+#include "config/the_isa.hh"
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
#include "cpu/profile.hh"
diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh
index 466d0d1c9..39961fb88 100644
--- a/src/cpu/simple/base.hh
+++ b/src/cpu/simple/base.hh
@@ -36,6 +36,7 @@
#include "arch/predecoder.hh"
#include "base/statistics.hh"
#include "config/full_system.hh"
+#include "config/the_isa.hh"
#include "cpu/base.hh"
#include "cpu/simple_thread.hh"
#include "cpu/pc_event.hh"
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index 672fd9414..6b22d2fcf 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -32,6 +32,7 @@
#include "arch/mmaped_ipr.hh"
#include "arch/utility.hh"
#include "base/bigint.hh"
+#include "config/the_isa.hh"
#include "cpu/exetrace.hh"
#include "cpu/simple/timing.hh"
#include "mem/packet.hh"
@@ -272,6 +273,8 @@ TimingSimpleCPU::sendData(Fault fault, RequestPtr req,
{
_status = Running;
if (fault != NoFault) {
+ if (req->isPrefetch())
+ fault = NoFault;
delete data;
delete req;
@@ -314,6 +317,10 @@ TimingSimpleCPU::sendSplitData(Fault fault1, Fault fault2,
{
_status = Running;
if (fault1 != NoFault || fault2 != NoFault) {
+ if (req1->isPrefetch())
+ fault1 = NoFault;
+ if (req2->isPrefetch())
+ fault2 = NoFault;
delete data;
delete req1;
delete req2;
@@ -359,6 +366,8 @@ TimingSimpleCPU::sendSplitData(Fault fault1, Fault fault2,
void
TimingSimpleCPU::translationFault(Fault fault)
{
+ // fault may be NoFault in cases where a fault is suppressed,
+ // for instance prefetches.
numCycles += tickToCycles(curTick - previousTick);
previousTick = curTick;
diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc
index 22bc283a3..ad69719ee 100644
--- a/src/cpu/simple_thread.cc
+++ b/src/cpu/simple_thread.cc
@@ -34,6 +34,7 @@
#include <string>
#include "arch/isa_traits.hh"
+#include "config/the_isa.hh"
#include "cpu/base.hh"
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
@@ -198,6 +199,11 @@ SimpleThread::serialize(ostream &os)
SERIALIZE_SCALAR(nextPC);
SERIALIZE_SCALAR(nextNPC);
// thread_num and cpu_id are deterministic from the config
+
+ //
+ // Now must serialize all the ISA dependent state
+ //
+ isa.serialize(cpu, os);
}
@@ -213,6 +219,11 @@ SimpleThread::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_SCALAR(nextPC);
UNSERIALIZE_SCALAR(nextNPC);
// thread_num and cpu_id are deterministic from the config
+
+ //
+ // Now must unserialize all the ISA dependent state
+ //
+ isa.unserialize(cpu, cp, section);
}
#if FULL_SYSTEM
diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh
index 8a44eba37..2d28607b4 100644
--- a/src/cpu/simple_thread.hh
+++ b/src/cpu/simple_thread.hh
@@ -39,6 +39,7 @@
#include "arch/types.hh"
#include "base/types.hh"
#include "config/full_system.hh"
+#include "config/the_isa.hh"
#include "cpu/thread_context.hh"
#include "cpu/thread_state.hh"
#include "mem/request.hh"
diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh
index b1298e0e9..fdec09756 100644
--- a/src/cpu/static_inst.hh
+++ b/src/cpu/static_inst.hh
@@ -36,6 +36,7 @@
#include "arch/isa_traits.hh"
#include "arch/utility.hh"
+#include "config/the_isa.hh"
#include "base/bitfield.hh"
#include "base/hashmap.hh"
#include "base/misc.hh"
diff --git a/src/cpu/thread_context.cc b/src/cpu/thread_context.cc
index ab105a435..f2083ef08 100644
--- a/src/cpu/thread_context.cc
+++ b/src/cpu/thread_context.cc
@@ -30,6 +30,7 @@
#include "base/misc.hh"
#include "base/trace.hh"
+#include "config/the_isa.hh"
#include "cpu/thread_context.hh"
void
diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh
index 9e34204ef..78ecdacf2 100644
--- a/src/cpu/thread_context.hh
+++ b/src/cpu/thread_context.hh
@@ -35,6 +35,7 @@
#include "arch/types.hh"
#include "base/types.hh"
#include "config/full_system.hh"
+#include "config/the_isa.hh"
#include "mem/request.hh"
#include "sim/byteswap.hh"
#include "sim/faults.hh"
diff --git a/src/cpu/thread_state.hh b/src/cpu/thread_state.hh
index 5c7c0ea56..cf637aeda 100644
--- a/src/cpu/thread_state.hh
+++ b/src/cpu/thread_state.hh
@@ -32,6 +32,7 @@
#define __CPU_THREAD_STATE_HH__
#include "arch/types.hh"
+#include "config/the_isa.hh"
#include "cpu/profile.hh"
#include "cpu/thread_context.hh"
#include "cpu/base.hh"
diff --git a/src/dev/Uart.py b/src/dev/Uart.py
index 5135a064d..9254dc695 100644
--- a/src/dev/Uart.py
+++ b/src/dev/Uart.py
@@ -28,7 +28,6 @@
from m5.params import *
from m5.proxy import *
-from m5 import build_env
from Device import BasicPioDevice
class Uart(BasicPioDevice):
diff --git a/src/dev/alpha/tsunami.cc b/src/dev/alpha/tsunami.cc
index b6478fe22..b36b5977d 100644
--- a/src/dev/alpha/tsunami.cc
+++ b/src/dev/alpha/tsunami.cc
@@ -36,6 +36,7 @@
#include <string>
#include <vector>
+#include "config/the_isa.hh"
#include "cpu/intr_control.hh"
#include "dev/alpha/tsunami_cchip.hh"
#include "dev/alpha/tsunami_pchip.hh"
diff --git a/src/dev/alpha/tsunami_cchip.cc b/src/dev/alpha/tsunami_cchip.cc
index 52a2aea14..fd76fd93e 100644
--- a/src/dev/alpha/tsunami_cchip.cc
+++ b/src/dev/alpha/tsunami_cchip.cc
@@ -39,6 +39,7 @@
#include "arch/alpha/ev5.hh"
#include "base/trace.hh"
+#include "config/the_isa.hh"
#include "cpu/intr_control.hh"
#include "cpu/thread_context.hh"
#include "dev/alpha/tsunami.hh"
diff --git a/src/dev/alpha/tsunami_io.cc b/src/dev/alpha/tsunami_io.cc
index 9c88904e3..8b06f5170 100644
--- a/src/dev/alpha/tsunami_io.cc
+++ b/src/dev/alpha/tsunami_io.cc
@@ -42,6 +42,7 @@
#include "base/time.hh"
#include "base/trace.hh"
+#include "config/the_isa.hh"
#include "dev/rtcreg.h"
#include "dev/alpha/tsunami_cchip.hh"
#include "dev/alpha/tsunami.hh"
diff --git a/src/dev/alpha/tsunami_pchip.cc b/src/dev/alpha/tsunami_pchip.cc
index 4df7d1150..df980cf79 100644
--- a/src/dev/alpha/tsunami_pchip.cc
+++ b/src/dev/alpha/tsunami_pchip.cc
@@ -38,6 +38,7 @@
#include <vector>
#include "base/trace.hh"
+#include "config/the_isa.hh"
#include "dev/alpha/tsunami_pchip.hh"
#include "dev/alpha/tsunamireg.h"
#include "dev/alpha/tsunami.hh"
diff --git a/src/dev/arm/SConscript b/src/dev/arm/SConscript
new file mode 100644
index 000000000..dd1d73e1a
--- /dev/null
+++ b/src/dev/arm/SConscript
@@ -0,0 +1,36 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2009 ARM Limited
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Ali Saidi
+
+Import('*')
+
+if env['FULL_SYSTEM'] and env['TARGET_ISA'] == 'arm':
+ SimObject('Versatile.py')
+
+ Source('versatile.cc')
diff --git a/src/dev/arm/Versatile.py b/src/dev/arm/Versatile.py
new file mode 100644
index 000000000..7f36bbcf3
--- /dev/null
+++ b/src/dev/arm/Versatile.py
@@ -0,0 +1,51 @@
+# Copyright (c) 2006-2007 The Regents of The University of Michigan
+# Copyright (c) 2009 ARM Limited
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Gabe Black
+
+from m5.params import *
+from m5.proxy import *
+from Device import BasicPioDevice, PioDevice, IsaFake, BadAddr
+from Platform import Platform
+from Terminal import Terminal
+from Uart import Uart8250
+
+
+class Versatile(Platform):
+ type = 'Versatile'
+ system = Param.System(Parent.any, "system")
+
+ # Attach I/O devices that are on chip
+ def attachOnChipIO(self, bus):
+ pass
+
+
+ # Attach I/O devices to specified bus object. Can't do this
+ # earlier, since the bus object itself is typically defined at the
+ # System level.
+ def attachIO(self, bus):
+ pass
diff --git a/src/dev/arm/versatile.cc b/src/dev/arm/versatile.cc
new file mode 100644
index 000000000..7d571db99
--- /dev/null
+++ b/src/dev/arm/versatile.cc
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * Copyright (c) 2009 ARM Limited
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ali Saidi
+ */
+
+/** @file
+ * Implementation of Versatile platform.
+ */
+
+#include <deque>
+#include <string>
+#include <vector>
+
+#include "config/the_isa.hh"
+#include "cpu/intr_control.hh"
+#include "dev/arm/versatile.hh"
+#include "dev/terminal.hh"
+#include "sim/system.hh"
+
+using namespace std;
+using namespace TheISA;
+
+Versatile::Versatile(const Params *p)
+ : Platform(p), system(p->system)
+{
+ // set the back pointer from the system to myself
+ system->platform = this;
+}
+
+Tick
+Versatile::intrFrequency()
+{
+ panic("Need implementation\n");
+ M5_DUMMY_RETURN
+}
+
+void
+Versatile::postConsoleInt()
+{
+ warn_once("Don't know what interrupt to post for console.\n");
+ //panic("Need implementation\n");
+}
+
+void
+Versatile::clearConsoleInt()
+{
+ warn_once("Don't know what interrupt to clear for console.\n");
+ //panic("Need implementation\n");
+}
+
+void
+Versatile::postPciInt(int line)
+{
+ panic("Need implementation\n");
+}
+
+void
+Versatile::clearPciInt(int line)
+{
+ panic("Need implementation\n");
+}
+
+Addr
+Versatile::pciToDma(Addr pciAddr) const
+{
+ panic("Need implementation\n");
+ M5_DUMMY_RETURN
+}
+
+
+Addr
+Versatile::calcPciConfigAddr(int bus, int dev, int func)
+{
+ panic("Need implementation\n");
+ M5_DUMMY_RETURN
+}
+
+Addr
+Versatile::calcPciIOAddr(Addr addr)
+{
+ panic("Need implementation\n");
+ M5_DUMMY_RETURN
+}
+
+Addr
+Versatile::calcPciMemAddr(Addr addr)
+{
+ panic("Need implementation\n");
+ M5_DUMMY_RETURN
+}
+
+Versatile *
+VersatileParams::create()
+{
+ return new Versatile(this);
+}
diff --git a/src/dev/arm/versatile.hh b/src/dev/arm/versatile.hh
new file mode 100644
index 000000000..edec3631c
--- /dev/null
+++ b/src/dev/arm/versatile.hh
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * Copyright (c) 2009 ARM Limited
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ali Saidi
+ */
+
+/**
+ * @file
+ * Declaration of top level class for the Versatile platform chips. This class just
+ * retains pointers to all its children so the children can communicate.
+ */
+
+#ifndef __DEV_ARM_VERSATILE_HH__
+#define __DEV_ARM_VERSATILE_HH__
+
+#include "dev/platform.hh"
+#include "params/Versatile.hh"
+
+class IdeController;
+class System;
+
+class Versatile : public Platform
+{
+ public:
+ /** Pointer to the system */
+ System *system;
+
+ public:
+ typedef VersatileParams Params;
+ /**
+ * Constructor for the Tsunami Class.
+ * @param name name of the object
+ * @param s system the object belongs to
+ * @param intctrl pointer to the interrupt controller
+ */
+ Versatile(const Params *p);
+
+ /**
+ * Return the interrupting frequency to AlphaAccess
+ * @return frequency of RTC interrupts
+ */
+ virtual Tick intrFrequency();
+
+ /**
+ * Cause the cpu to post a serial interrupt to the CPU.
+ */
+ virtual void postConsoleInt();
+
+ /**
+ * Clear a posted CPU interrupt
+ */
+ virtual void clearConsoleInt();
+
+ /**
+ * Cause the chipset to post a cpi interrupt to the CPU.
+ */
+ virtual void postPciInt(int line);
+
+ /**
+ * Clear a posted PCI->CPU interrupt
+ */
+ virtual void clearPciInt(int line);
+
+
+ virtual Addr pciToDma(Addr pciAddr) const;
+
+ /**
+ * Calculate the configuration address given a bus/dev/func.
+ */
+ virtual Addr calcPciConfigAddr(int bus, int dev, int func);
+
+ /**
+ * Calculate the address for an IO location on the PCI bus.
+ */
+ virtual Addr calcPciIOAddr(Addr addr);
+
+ /**
+ * Calculate the address for a memory location on the PCI bus.
+ */
+ virtual Addr calcPciMemAddr(Addr addr);
+};
+
+#endif // __DEV_ARM_VERSATILE_HH__
diff --git a/src/dev/baddev.cc b/src/dev/baddev.cc
index 6cdee0310..356574c71 100644
--- a/src/dev/baddev.cc
+++ b/src/dev/baddev.cc
@@ -37,6 +37,7 @@
#include <vector>
#include "base/trace.hh"
+#include "config/the_isa.hh"
#include "dev/baddev.hh"
#include "dev/platform.hh"
#include "mem/port.hh"
diff --git a/src/dev/ide_ctrl.cc b/src/dev/ide_ctrl.cc
index a8cceda1f..87dc0b2aa 100644
--- a/src/dev/ide_ctrl.cc
+++ b/src/dev/ide_ctrl.cc
@@ -75,8 +75,6 @@ IdeController::Channel::Channel(
IdeController::Channel::~Channel()
{
- delete master;
- delete slave;
}
IdeController::IdeController(Params *p)
diff --git a/src/dev/ide_disk.cc b/src/dev/ide_disk.cc
index 83faf508e..fe93924f9 100644
--- a/src/dev/ide_disk.cc
+++ b/src/dev/ide_disk.cc
@@ -39,6 +39,7 @@
#include <string>
#include "arch/isa_traits.hh"
+#include "config/the_isa.hh"
#include "base/chunk_generator.hh"
#include "base/cprintf.hh" // csprintf
#include "base/trace.hh"
diff --git a/src/dev/mc146818.cc b/src/dev/mc146818.cc
index b25b015d2..2e6ed2a4b 100644
--- a/src/dev/mc146818.cc
+++ b/src/dev/mc146818.cc
@@ -105,6 +105,8 @@ MC146818::MC146818(EventManager *em, const string &n, const struct tm time,
MC146818::~MC146818()
{
+ deschedule(tickEvent);
+ deschedule(event);
}
void
@@ -207,6 +209,15 @@ MC146818::serialize(const string &base, ostream &os)
arrayParamOut(os, base + ".clock_data", clock_data, sizeof(clock_data));
paramOut(os, base + ".stat_regA", stat_regA);
paramOut(os, base + ".stat_regB", stat_regB);
+
+ //
+ // save the timer tick and rtc clock tick values to correctly reschedule
+ // them during unserialize
+ //
+ Tick rtcTimerInterruptTickOffset = event.when() - curTick;
+ SERIALIZE_SCALAR(rtcTimerInterruptTickOffset);
+ Tick rtcClockTickOffset = event.when() - curTick;
+ SERIALIZE_SCALAR(rtcClockTickOffset);
}
void
@@ -218,10 +229,15 @@ MC146818::unserialize(const string &base, Checkpoint *cp,
paramIn(cp, section, base + ".stat_regA", stat_regA);
paramIn(cp, section, base + ".stat_regB", stat_regB);
- // We're not unserializing the event here, but we need to
- // rescehedule the event since curTick was moved forward by the
- // checkpoint
- reschedule(event, curTick + event.interval);
+ //
+ // properly schedule the timer and rtc clock events
+ //
+ Tick rtcTimerInterruptTickOffset;
+ UNSERIALIZE_SCALAR(rtcTimerInterruptTickOffset);
+ reschedule(event, curTick + rtcTimerInterruptTickOffset);
+ Tick rtcClockTickOffset;
+ UNSERIALIZE_SCALAR(rtcClockTickOffset);
+ reschedule(tickEvent, curTick + rtcClockTickOffset);
}
MC146818::RTCEvent::RTCEvent(MC146818 * _parent, Tick i)
diff --git a/src/dev/mips/malta.cc b/src/dev/mips/malta.cc
index 1401fe9ee..73dc9f116 100755
--- a/src/dev/mips/malta.cc
+++ b/src/dev/mips/malta.cc
@@ -37,6 +37,7 @@
#include <string>
#include <vector>
+#include "config/the_isa.hh"
#include "cpu/intr_control.hh"
#include "dev/mips/malta_cchip.hh"
#include "dev/mips/malta_pchip.hh"
@@ -46,7 +47,6 @@
#include "params/Malta.hh"
#include "sim/system.hh"
-
using namespace std;
using namespace TheISA;
diff --git a/src/dev/mips/malta_cchip.cc b/src/dev/mips/malta_cchip.cc
index 265977665..b2d5069c5 100755
--- a/src/dev/mips/malta_cchip.cc
+++ b/src/dev/mips/malta_cchip.cc
@@ -39,6 +39,7 @@
#include "arch/mips/mips_core_specific.hh"
#include "base/trace.hh"
+#include "config/the_isa.hh"
#include "cpu/intr_control.hh"
#include "cpu/thread_context.hh"
#include "dev/mips/malta.hh"
@@ -56,7 +57,7 @@ using namespace TheISA;
MaltaCChip::MaltaCChip(Params *p)
: BasicPioDevice(p), malta(p->malta)
{
- warn("MaltaCCHIP::MaltaCChip() not implemented.");
+ warn("MaltaCCHIP::MaltaCChip() not implemented.");
pioSize = 0xfffffff;
//Put back pointer in malta
diff --git a/src/dev/mips/malta_io.cc b/src/dev/mips/malta_io.cc
index 7f04789db..5a738a9b4 100755
--- a/src/dev/mips/malta_io.cc
+++ b/src/dev/mips/malta_io.cc
@@ -42,6 +42,7 @@
#include "base/time.hh"
#include "base/trace.hh"
+#include "config/the_isa.hh"
#include "dev/rtcreg.h"
#include "dev/mips/malta_cchip.hh"
#include "dev/mips/malta.hh"
diff --git a/src/dev/mips/malta_pchip.cc b/src/dev/mips/malta_pchip.cc
index b357e3b61..035433021 100755
--- a/src/dev/mips/malta_pchip.cc
+++ b/src/dev/mips/malta_pchip.cc
@@ -38,6 +38,7 @@
#include <vector>
#include "base/trace.hh"
+#include "config/the_isa.hh"
#include "dev/mips/malta_pchip.hh"
#include "dev/mips/maltareg.h"
#include "dev/mips/malta.hh"
diff --git a/src/dev/ns_gige.cc b/src/dev/ns_gige.cc
index 912ca7f0f..86f081ec5 100644
--- a/src/dev/ns_gige.cc
+++ b/src/dev/ns_gige.cc
@@ -39,6 +39,7 @@
#include "base/debug.hh"
#include "base/inet.hh"
#include "base/types.hh"
+#include "config/the_isa.hh"
#include "cpu/thread_context.hh"
#include "dev/etherlink.hh"
#include "dev/ns_gige.hh"
diff --git a/src/dev/platform.cc b/src/dev/platform.cc
index 2b51a6245..a91a5abf9 100644
--- a/src/dev/platform.cc
+++ b/src/dev/platform.cc
@@ -30,6 +30,7 @@
*/
#include "base/misc.hh"
+#include "config/the_isa.hh"
#include "dev/platform.hh"
#include "sim/sim_exit.hh"
diff --git a/src/dev/sinic.cc b/src/dev/sinic.cc
index 133f70b0b..86090e048 100644
--- a/src/dev/sinic.cc
+++ b/src/dev/sinic.cc
@@ -36,6 +36,7 @@
#include "base/debug.hh"
#include "base/inet.hh"
#include "base/types.hh"
+#include "config/the_isa.hh"
#include "cpu/intr_control.hh"
#include "cpu/thread_context.hh"
#include "dev/etherlink.hh"
diff --git a/src/dev/sparc/dtod.cc b/src/dev/sparc/dtod.cc
index 81132ac65..c7243cfb8 100644
--- a/src/dev/sparc/dtod.cc
+++ b/src/dev/sparc/dtod.cc
@@ -39,6 +39,7 @@
#include "base/time.hh"
#include "base/trace.hh"
+#include "config/the_isa.hh"
#include "dev/sparc/dtod.hh"
#include "dev/platform.hh"
#include "mem/packet_access.hh"
diff --git a/src/dev/sparc/iob.cc b/src/dev/sparc/iob.cc
index 4543dd07b..40f856d8a 100644
--- a/src/dev/sparc/iob.cc
+++ b/src/dev/sparc/iob.cc
@@ -90,20 +90,18 @@ void
Iob::readIob(PacketPtr pkt)
{
Addr accessAddr = pkt->getAddr() - iobManAddr;
- int index;
- uint64_t data;
if (accessAddr >= IntManAddr && accessAddr < IntManAddr + IntManSize) {
- index = (accessAddr - IntManAddr) >> 3;
- data = intMan[index].cpu << 8 | intMan[index].vector << 0;
+ int index = (accessAddr - IntManAddr) >> 3;
+ uint64_t data = intMan[index].cpu << 8 | intMan[index].vector << 0;
pkt->set(data);
return;
}
if (accessAddr >= IntCtlAddr && accessAddr < IntCtlAddr + IntCtlSize) {
- index = (accessAddr - IntManAddr) >> 3;
- data = intCtl[index].mask ? 1 << 2 : 0 |
- intCtl[index].pend ? 1 << 0 : 0;
+ int index = (accessAddr - IntCtlAddr) >> 3;
+ uint64_t data = intCtl[index].mask ? 1 << 2 : 0 |
+ intCtl[index].pend ? 1 << 0 : 0;
pkt->set(data);
return;
}
@@ -199,7 +197,7 @@ Iob::writeIob(PacketPtr pkt)
}
if (accessAddr >= IntCtlAddr && accessAddr < IntCtlAddr + IntCtlSize) {
- index = (accessAddr - IntManAddr) >> 3;
+ index = (accessAddr - IntCtlAddr) >> 3;
data = pkt->get<uint64_t>();
intCtl[index].mask = bits(data,2,2);
if (bits(data,1,1))
diff --git a/src/dev/sparc/t1000.cc b/src/dev/sparc/t1000.cc
index 88fb358ef..c00d942c9 100644
--- a/src/dev/sparc/t1000.cc
+++ b/src/dev/sparc/t1000.cc
@@ -36,6 +36,7 @@
#include <string>
#include <vector>
+#include "config/the_isa.hh"
#include "cpu/intr_control.hh"
#include "dev/sparc/t1000.hh"
#include "dev/terminal.hh"
diff --git a/src/dev/uart8250.cc b/src/dev/uart8250.cc
index 93f71f49b..e3eacaaa2 100644
--- a/src/dev/uart8250.cc
+++ b/src/dev/uart8250.cc
@@ -38,6 +38,7 @@
#include "base/inifile.hh"
#include "base/str.hh" // for to_number
#include "base/trace.hh"
+#include "config/the_isa.hh"
#include "dev/platform.hh"
#include "dev/terminal.hh"
#include "dev/uart8250.hh"
diff --git a/src/dev/x86/i82094aa.cc b/src/dev/x86/i82094aa.cc
index ed936d0cb..591fee6a4 100644
--- a/src/dev/x86/i82094aa.cc
+++ b/src/dev/x86/i82094aa.cc
@@ -151,7 +151,7 @@ X86ISA::I82094AA::signalInterrupt(int line)
DPRINTF(I82094AA, "Entry was masked.\n");
return;
} else {
- TriggerIntMessage message;
+ TriggerIntMessage message = 0;
message.destination = entry.dest;
if (entry.deliveryMode == DeliveryMode::ExtInt) {
assert(extIntPic);
diff --git a/src/dev/x86/pc.cc b/src/dev/x86/pc.cc
index 7dc1d8711..e3449abf6 100644
--- a/src/dev/x86/pc.cc
+++ b/src/dev/x86/pc.cc
@@ -38,6 +38,7 @@
#include "arch/x86/intmessage.hh"
#include "arch/x86/x86_traits.hh"
+#include "config/the_isa.hh"
#include "cpu/intr_control.hh"
#include "dev/terminal.hh"
#include "dev/x86/i82094aa.hh"
diff --git a/src/kern/linux/linux.cc b/src/kern/linux/linux.cc
index abe7c0b75..72f1832b8 100644
--- a/src/kern/linux/linux.cc
+++ b/src/kern/linux/linux.cc
@@ -28,6 +28,7 @@
* Authors: Ali Saidi
*/
+#include <cstdio>
#include <string>
#include "cpu/thread_context.hh"
diff --git a/src/kern/linux/linux.hh b/src/kern/linux/linux.hh
index 7c16228ea..7fe107139 100644
--- a/src/kern/linux/linux.hh
+++ b/src/kern/linux/linux.hh
@@ -62,6 +62,7 @@ class Linux : public OperatingSystem
typedef uint64_t size_t;
typedef uint64_t off_t;
typedef int64_t time_t;
+ typedef int64_t clock_t;
typedef uint32_t uid_t;
typedef uint32_t gid_t;
//@}
@@ -136,6 +137,17 @@ class Linux : public OperatingSystem
int64_t tv_usec; //!< microseconds
};
+ /// Clock ticks per second, for times().
+ static const int M5_SC_CLK_TCK = 100;
+
+ /// For times().
+ struct tms {
+ int64_t tms_utime; //!< user time
+ int64_t tms_stime; //!< system time
+ int64_t tms_cutime; //!< user time of children
+ int64_t tms_cstime; //!< system time of children
+ };
+
// For writev/readv
struct tgt_iovec {
uint64_t iov_base; // void *
diff --git a/src/kern/linux/printk.hh b/src/kern/linux/printk.hh
index da9564b7e..5c6ee073d 100644
--- a/src/kern/linux/printk.hh
+++ b/src/kern/linux/printk.hh
@@ -32,8 +32,6 @@
#ifndef __PRINTK_HH__
#define __PRINTK_HH__
-#include "arch/isa_specific.hh"
-
#include <sstream>
class Arguments;
diff --git a/src/kern/operatingsystem.hh b/src/kern/operatingsystem.hh
index 47e64ffd9..6574e3c6b 100644
--- a/src/kern/operatingsystem.hh
+++ b/src/kern/operatingsystem.hh
@@ -122,6 +122,10 @@ class OperatingSystem {
static int openSpecialFile(std::string path, LiveProcess *process, ThreadContext *tc);
+ static const bool mmapGrowsUp = true;
+
+ static bool mmapGrowsDown() { return false; }
+
}; // class OperatingSystem
diff --git a/src/kern/system_events.cc b/src/kern/system_events.cc
index 6fd9e1563..bd01ed9ed 100644
--- a/src/kern/system_events.cc
+++ b/src/kern/system_events.cc
@@ -29,9 +29,9 @@
* Nathan Binkert
*/
-//For ISA_HAS_DELAY_SLOT
#include "arch/isa_traits.hh"
#include "base/trace.hh"
+#include "config/the_isa.hh"
#include "cpu/thread_context.hh"
#include "kern/system_events.hh"
diff --git a/src/kern/tru64/dump_mbuf.cc b/src/kern/tru64/dump_mbuf.cc
index 517aad6fa..207d30792 100644
--- a/src/kern/tru64/dump_mbuf.cc
+++ b/src/kern/tru64/dump_mbuf.cc
@@ -37,6 +37,7 @@
#include "base/loader/symtab.hh"
#include "base/trace.hh"
#include "base/types.hh"
+#include "config/the_isa.hh"
#include "cpu/thread_context.hh"
#include "kern/tru64/mbuf.hh"
#include "sim/arguments.hh"
diff --git a/src/kern/tru64/tru64.hh b/src/kern/tru64/tru64.hh
index bf46e0de4..033f30946 100644
--- a/src/kern/tru64/tru64.hh
+++ b/src/kern/tru64/tru64.hh
@@ -31,6 +31,7 @@
#ifndef __TRU64_HH__
#define __TRU64_HH__
+
#include "config/full_system.hh"
#include "kern/operatingsystem.hh"
@@ -55,6 +56,7 @@ class Tru64 {};
#include <string.h> // for memset()
#include <unistd.h>
+#include "config/the_isa.hh"
#include "arch/alpha/registers.hh"
#include "cpu/base.hh"
#include "sim/core.hh"
@@ -438,10 +440,11 @@ class Tru64 : public OperatingSystem
#ifdef __CYGWIN__
panic("getdirent not implemented on cygwin!");
#else
- int fd = process->sim_fd(process->getSyscallArg(tc, 0));
- Addr tgt_buf = process->getSyscallArg(tc, 1);
- int tgt_nbytes = process->getSyscallArg(tc, 2);
- Addr tgt_basep = process->getSyscallArg(tc, 3);
+ int index = 0;
+ int fd = process->sim_fd(process->getSyscallArg(tc, index));
+ Addr tgt_buf = process->getSyscallArg(tc, index);
+ int tgt_nbytes = process->getSyscallArg(tc, index);
+ Addr tgt_basep = process->getSyscallArg(tc, index);
char * const host_buf = new char[tgt_nbytes];
@@ -496,7 +499,8 @@ class Tru64 : public OperatingSystem
{
using namespace TheISA;
- TypedBufferArg<Tru64::sigcontext> sc(process->getSyscallArg(tc, 0));
+ int index = 0;
+ TypedBufferArg<Tru64::sigcontext> sc(process->getSyscallArg(tc, index));
sc.copyIn(tc->getMemPort());
@@ -528,7 +532,8 @@ class Tru64 : public OperatingSystem
{
using namespace TheISA;
- TypedBufferArg<Tru64::vm_stack> argp(process->getSyscallArg(tc, 0));
+ int index = 0;
+ TypedBufferArg<Tru64::vm_stack> argp(process->getSyscallArg(tc, index));
argp.copyIn(tc->getMemPort());
@@ -576,9 +581,10 @@ class Tru64 : public OperatingSystem
using namespace std;
using namespace TheISA;
+ int index = 0;
TypedBufferArg<Tru64::nxm_task_attr>
- attrp(process->getSyscallArg(tc, 0));
- TypedBufferArg<Addr> configptr_ptr(process->getSyscallArg(tc, 1));
+ attrp(process->getSyscallArg(tc, index));
+ TypedBufferArg<Addr> configptr_ptr(process->getSyscallArg(tc, index));
attrp.copyIn(tc->getMemPort());
@@ -710,10 +716,11 @@ class Tru64 : public OperatingSystem
using namespace std;
using namespace TheISA;
+ int index = 0;
TypedBufferArg<Tru64::nxm_thread_attr>
- attrp(process->getSyscallArg(tc, 0));
- TypedBufferArg<uint64_t> kidp(process->getSyscallArg(tc, 1));
- int thread_index = process->getSyscallArg(tc, 2);
+ attrp(process->getSyscallArg(tc, index));
+ TypedBufferArg<uint64_t> kidp(process->getSyscallArg(tc, index));
+ int thread_index = process->getSyscallArg(tc, index);
// get attribute args
attrp.copyIn(tc->getMemPort());
@@ -832,11 +839,12 @@ class Tru64 : public OperatingSystem
{
using namespace std;
- uint64_t tid = process->getSyscallArg(tc, 0);
- uint64_t secs = process->getSyscallArg(tc, 1);
- uint64_t flags = process->getSyscallArg(tc, 2);
- uint64_t action = process->getSyscallArg(tc, 3);
- uint64_t usecs = process->getSyscallArg(tc, 4);
+ int index = 0;
+ uint64_t tid = process->getSyscallArg(tc, index);
+ uint64_t secs = process->getSyscallArg(tc, index);
+ uint64_t flags = process->getSyscallArg(tc, index);
+ uint64_t action = process->getSyscallArg(tc, index);
+ uint64_t usecs = process->getSyscallArg(tc, index);
cout << tc->getCpuPtr()->name() << ": nxm_thread_block " << tid << " "
<< secs << " " << flags << " " << action << " " << usecs << endl;
@@ -851,11 +859,12 @@ class Tru64 : public OperatingSystem
{
using namespace std;
- Addr uaddr = process->getSyscallArg(tc, 0);
- uint64_t val = process->getSyscallArg(tc, 1);
- uint64_t secs = process->getSyscallArg(tc, 2);
- uint64_t usecs = process->getSyscallArg(tc, 3);
- uint64_t flags = process->getSyscallArg(tc, 4);
+ int index = 0;
+ Addr uaddr = process->getSyscallArg(tc, index);
+ uint64_t val = process->getSyscallArg(tc, index);
+ uint64_t secs = process->getSyscallArg(tc, index);
+ uint64_t usecs = process->getSyscallArg(tc, index);
+ uint64_t flags = process->getSyscallArg(tc, index);
BaseCPU *cpu = tc->getCpuPtr();
@@ -874,7 +883,8 @@ class Tru64 : public OperatingSystem
{
using namespace std;
- Addr uaddr = process->getSyscallArg(tc, 0);
+ int index = 0;
+ Addr uaddr = process->getSyscallArg(tc, index);
cout << tc->getCpuPtr()->name() << ": nxm_unblock "
<< hex << uaddr << dec << endl;
@@ -975,7 +985,8 @@ class Tru64 : public OperatingSystem
m5_mutex_lockFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- Addr uaddr = process->getSyscallArg(tc, 0);
+ int index = 0;
+ Addr uaddr = process->getSyscallArg(tc, index);
m5_lock_mutex(uaddr, process, tc);
@@ -992,7 +1003,8 @@ class Tru64 : public OperatingSystem
{
using namespace TheISA;
- Addr uaddr = process->getSyscallArg(tc, 0);
+ int index = 0;
+ Addr uaddr = process->getSyscallArg(tc, index);
TypedBufferArg<uint64_t> lockp(uaddr);
lockp.copyIn(tc->getMemPort());
@@ -1012,7 +1024,8 @@ class Tru64 : public OperatingSystem
m5_mutex_unlockFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- Addr uaddr = process->getSyscallArg(tc, 0);
+ int index = 0;
+ Addr uaddr = process->getSyscallArg(tc, index);
m5_unlock_mutex(uaddr, process, tc);
@@ -1024,7 +1037,8 @@ class Tru64 : public OperatingSystem
m5_cond_signalFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- Addr cond_addr = process->getSyscallArg(tc, 0);
+ int index = 0;
+ Addr cond_addr = process->getSyscallArg(tc, index);
// Wake up one process waiting on the condition variable.
activate_waiting_context(cond_addr, process);
@@ -1037,7 +1051,8 @@ class Tru64 : public OperatingSystem
m5_cond_broadcastFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- Addr cond_addr = process->getSyscallArg(tc, 0);
+ int index = 0;
+ Addr cond_addr = process->getSyscallArg(tc, index);
activate_waiting_context(cond_addr, process, true);
@@ -1051,8 +1066,9 @@ class Tru64 : public OperatingSystem
{
using namespace TheISA;
- Addr cond_addr = process->getSyscallArg(tc, 0);
- Addr lock_addr = process->getSyscallArg(tc, 1);
+ int index = 0;
+ Addr cond_addr = process->getSyscallArg(tc, index);
+ Addr lock_addr = process->getSyscallArg(tc, index);
TypedBufferArg<uint64_t> condp(cond_addr);
TypedBufferArg<uint64_t> lockp(lock_addr);
@@ -1084,10 +1100,11 @@ class Tru64 : public OperatingSystem
indirectSyscallFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- int new_callnum = process->getSyscallArg(tc, 0);
+ int index = 0;
+ int new_callnum = process->getSyscallArg(tc, index);
for (int i = 0; i < 5; ++i)
- process->setSyscallArg(tc, i, process->getSyscallArg(tc, i+1));
+ process->setSyscallArg(tc, i, process->getSyscallArg(tc, index));
SyscallDesc *new_desc = process->getDesc(new_callnum);
diff --git a/src/kern/tru64/tru64_events.cc b/src/kern/tru64/tru64_events.cc
index 4867df559..460f75dea 100644
--- a/src/kern/tru64/tru64_events.cc
+++ b/src/kern/tru64/tru64_events.cc
@@ -31,6 +31,7 @@
#include "arch/alpha/ev5.hh"
#include "arch/isa_traits.hh"
+#include "config/the_isa.hh"
#include "cpu/thread_context.hh"
#include "cpu/base.hh"
#include "kern/system_events.hh"
diff --git a/src/mem/Bus.py b/src/mem/Bus.py
index 0f113cc09..b3f6b2946 100644
--- a/src/mem/Bus.py
+++ b/src/mem/Bus.py
@@ -26,12 +26,12 @@
#
# Authors: Nathan Binkert
-from m5 import build_env
+from m5.defines import buildEnv
from m5.params import *
from m5.proxy import *
from MemObject import MemObject
-if build_env['FULL_SYSTEM']:
+if buildEnv['FULL_SYSTEM']:
from Device import BadAddr
class Bus(MemObject):
diff --git a/src/mem/RubyMemory.py b/src/mem/RubyMemory.py
index fbbbeebe4..2ad794a3f 100644
--- a/src/mem/RubyMemory.py
+++ b/src/mem/RubyMemory.py
@@ -42,4 +42,7 @@ class RubyMemory(PhysicalMemory):
debug = Param.Bool(False, "Use ruby debug")
debug_file = Param.String("ruby.debug",
"path to the Ruby debug output file (stdout if blank)")
-
+ num_dmas = Param.Int(0, "Number of DMA ports connected to the Ruby memory")
+ dma_port = VectorPort("Ruby_dma_ports")
+ pio_port = Port("Ruby_pio_port")
+ ports_per_core = Param.Int(2, "Number of per core. Typical two: icache + dcache")
diff --git a/src/mem/SConscript b/src/mem/SConscript
index 21335a709..2188850e0 100644
--- a/src/mem/SConscript
+++ b/src/mem/SConscript
@@ -63,3 +63,4 @@ TraceFlag('BusBridge')
TraceFlag('LLSC')
TraceFlag('MMU')
TraceFlag('MemoryAccess')
+TraceFlag('Ruby')
diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc
index cc9b83d3e..d0135fc9d 100644
--- a/src/mem/bridge.cc
+++ b/src/mem/bridge.cc
@@ -93,7 +93,9 @@ Bridge::init()
fatal("Both ports of bus bridge are not connected to a bus.\n");
if (portA.peerBlockSize() != portB.peerBlockSize())
- fatal("Busses don't have the same block size... Not supported.\n");
+ fatal("port A size %d, port B size %d \n " \
+ "Busses don't have the same block size... Not supported.\n",
+ portA.peerBlockSize(), portB.peerBlockSize());
}
bool
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index 001c37a24..cac08d1a8 100644
--- a/src/mem/bus.cc
+++ b/src/mem/bus.cc
@@ -244,6 +244,9 @@ Bus::recvTiming(PacketPtr pkt)
// Packet not successfully sent. Leave or put it on the retry list.
// illegal to block responses... can lead to deadlock
assert(!pkt->isResponse());
+ // It's also illegal to force a transaction to retry after
+ // someone else has committed to respond.
+ assert(!pkt->memInhibitAsserted());
DPRINTF(Bus, "recvTiming: src %d dst %d %s 0x%x TGT RETRY\n",
src, pkt->getDest(), pkt->cmdString(), pkt->getAddr());
addToRetryList(src_port);
diff --git a/src/mem/cache/BaseCache.py b/src/mem/cache/BaseCache.py
index bdef07cb4..5ded05400 100644
--- a/src/mem/cache/BaseCache.py
+++ b/src/mem/cache/BaseCache.py
@@ -68,8 +68,6 @@ class BaseCache(MemObject):
"Latency of the prefetcher")
prefetch_policy = Param.Prefetch('none',
"Type of prefetcher to use")
- prefetch_cache_check_push = Param.Bool(True,
- "Check if in cache on push or pop of prefetch queue")
prefetch_use_cpu_id = Param.Bool(True,
"Use the CPU ID to separate calculations of prefetches")
prefetch_data_accesses_only = Param.Bool(False,
diff --git a/src/mem/cache/base.hh b/src/mem/cache/base.hh
index 24f993383..c245fecd2 100644
--- a/src/mem/cache/base.hh
+++ b/src/mem/cache/base.hh
@@ -379,7 +379,7 @@ class BaseCache : public MemObject
}
- Addr blockAlign(Addr addr) const { return (addr & ~(blkSize - 1)); }
+ Addr blockAlign(Addr addr) const { return (addr & ~(Addr(blkSize - 1))); }
const Range<Addr> &getAddrRange() const { return addrRange; }
diff --git a/src/mem/cache/builder.cc b/src/mem/cache/builder.cc
index 599353b88..bd9eb9acc 100644
--- a/src/mem/cache/builder.cc
+++ b/src/mem/cache/builder.cc
@@ -33,9 +33,10 @@
* @file
* Simobject instatiation of caches.
*/
+#include <list>
#include <vector>
-// Must be included first to determine which caches we want
+#include "config/the_isa.hh"
#include "enums/Prefetch.hh"
#include "mem/config/cache.hh"
#include "mem/cache/base.hh"
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index 80b7c545c..429928c79 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -449,7 +449,7 @@ Cache<TagStore>::timingAccess(PacketPtr pkt)
} else {
// miss
- Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
+ Addr blk_addr = blockAlign(pkt->getAddr());
MSHR *mshr = mshrQueue.findMatch(blk_addr);
if (mshr) {
@@ -692,7 +692,7 @@ Cache<TagStore>::functionalAccess(PacketPtr pkt,
CachePort *incomingPort,
CachePort *otherSidePort)
{
- Addr blk_addr = pkt->getAddr() & ~(blkSize - 1);
+ Addr blk_addr = blockAlign(pkt->getAddr());
BlkType *blk = tags->findBlock(pkt->getAddr());
pkt->pushLabel(name());
@@ -1162,7 +1162,7 @@ Cache<TagStore>::snoopTiming(PacketPtr pkt)
BlkType *blk = tags->findBlock(pkt->getAddr());
- Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
+ Addr blk_addr = blockAlign(pkt->getAddr());
MSHR *mshr = mshrQueue.findMatch(blk_addr);
// Let the MSHR itself track the snoop and decide whether we want
@@ -1301,11 +1301,14 @@ Cache<TagStore>::getNextMSHR()
// If we have a miss queue slot, we can try a prefetch
PacketPtr pkt = prefetcher->getPacket();
if (pkt) {
- // Update statistic on number of prefetches issued
- // (hwpf_mshr_misses)
- mshr_misses[pkt->cmdToIndex()][0/*pkt->req->threadId()*/]++;
- // Don't request bus, since we already have it
- return allocateMissBuffer(pkt, curTick, false);
+ Addr pf_addr = blockAlign(pkt->getAddr());
+ if (!tags->findBlock(pf_addr) && !mshrQueue.findMatch(pf_addr)) {
+ // Update statistic on number of prefetches issued
+ // (hwpf_mshr_misses)
+ mshr_misses[pkt->cmdToIndex()][0/*pkt->req->threadId()*/]++;
+ // Don't request bus, since we already have it
+ return allocateMissBuffer(pkt, curTick, false);
+ }
}
}
diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc
index f20a306cb..ad7a0c882 100644
--- a/src/mem/cache/prefetch/base.cc
+++ b/src/mem/cache/prefetch/base.cc
@@ -33,17 +33,18 @@
* Hardware Prefetcher Definition.
*/
+#include <list>
+
#include "arch/isa_traits.hh"
#include "base/trace.hh"
+#include "config/the_isa.hh"
#include "mem/cache/base.hh"
#include "mem/cache/prefetch/base.hh"
#include "mem/request.hh"
-#include <list>
BasePrefetcher::BasePrefetcher(const BaseCacheParams *p)
: size(p->prefetcher_size), pageStop(!p->prefetch_past_page),
serialSquash(p->prefetch_serial_squash),
- cacheCheckPush(p->prefetch_cache_check_push),
onlyData(p->prefetch_data_accesses_only)
{
}
@@ -141,9 +142,6 @@ BasePrefetcher::getPacket()
do {
pkt = *pf.begin();
pf.pop_front();
- if (!cacheCheckPush) {
- keep_trying = cache->inCache(pkt->getAddr());
- }
if (keep_trying) {
DPRINTF(HWPrefetch, "addr 0x%x in cache, skipping\n",
@@ -224,18 +222,6 @@ BasePrefetcher::notify(PacketPtr &pkt, Tick time)
"inserting into prefetch queue with delay %d time %d\n",
addr, *delayIter, time);
- // Check if it is already in the cache
- if (cacheCheckPush && cache->inCache(addr)) {
- DPRINTF(HWPrefetch, "Prefetch addr already in cache\n");
- continue;
- }
-
- // Check if it is already in the miss_queue
- if (cache->inMissQueue(addr)) {
- DPRINTF(HWPrefetch, "Prefetch addr already in miss queue\n");
- continue;
- }
-
// Check if it is already in the pf buffer
if (inPrefetch(addr) != pf.end()) {
pfBufferHit++;
diff --git a/src/mem/cache/prefetch/base.hh b/src/mem/cache/prefetch/base.hh
index b5f33a455..e3c0cbf16 100644
--- a/src/mem/cache/prefetch/base.hh
+++ b/src/mem/cache/prefetch/base.hh
@@ -68,10 +68,6 @@ class BasePrefetcher
/** Do we remove prefetches with later times than a new miss.*/
bool serialSquash;
- /** Do we check if it is in the cache when inserting into buffer,
- or removing.*/
- bool cacheCheckPush;
-
/** Do we prefetch on only data reads, or on inst reads as well. */
bool onlyData;
diff --git a/src/mem/packet.hh b/src/mem/packet.hh
index 07c086cd5..c58862270 100644
--- a/src/mem/packet.hh
+++ b/src/mem/packet.hh
@@ -437,6 +437,7 @@ class Packet : public FastAlloc, public Printable
bool hadBadAddress() const { return cmd == MemCmd::BadAddressError; }
void copyError(Packet *pkt) { assert(pkt->isError()); cmd = pkt->cmd; }
+ bool isSrcValid() { return flags.isSet(VALID_SRC); }
/// Accessor function to get the source index of the packet.
NodeID getSrc() const { assert(flags.isSet(VALID_SRC)); return src; }
/// Accessor function to set the source index of the packet.
@@ -444,6 +445,7 @@ class Packet : public FastAlloc, public Printable
/// Reset source field, e.g. to retransmit packet on different bus.
void clearSrc() { flags.clear(VALID_SRC); }
+ bool isDestValid() { return flags.isSet(VALID_DST); }
/// Accessor function for the destination index of the packet.
NodeID getDest() const { assert(flags.isSet(VALID_DST)); return dest; }
/// Accessor function to set the destination index of the packet.
diff --git a/src/mem/packet_access.hh b/src/mem/packet_access.hh
index f70d508b2..fca9606fc 100644
--- a/src/mem/packet_access.hh
+++ b/src/mem/packet_access.hh
@@ -31,6 +31,7 @@
#include "arch/isa_traits.hh"
#include "base/bigint.hh"
+#include "config/the_isa.hh"
#include "mem/packet.hh"
#include "sim/byteswap.hh"
diff --git a/src/mem/page_table.cc b/src/mem/page_table.cc
index bf35932a6..4bc3a4434 100644
--- a/src/mem/page_table.cc
+++ b/src/mem/page_table.cc
@@ -42,6 +42,7 @@
#include "base/bitfield.hh"
#include "base/intmath.hh"
#include "base/trace.hh"
+#include "config/the_isa.hh"
#include "mem/page_table.hh"
#include "sim/process.hh"
#include "sim/sim_object.hh"
diff --git a/src/mem/page_table.hh b/src/mem/page_table.hh
index 3ce720ad4..0d93d37c7 100644
--- a/src/mem/page_table.hh
+++ b/src/mem/page_table.hh
@@ -42,6 +42,7 @@
#include "arch/tlb.hh"
#include "base/hashmap.hh"
#include "base/types.hh"
+#include "config/the_isa.hh"
#include "mem/request.hh"
#include "sim/faults.hh"
#include "sim/serialize.hh"
diff --git a/src/mem/physical.cc b/src/mem/physical.cc
index d87ad3b22..121a6e447 100644
--- a/src/mem/physical.cc
+++ b/src/mem/physical.cc
@@ -36,6 +36,7 @@
#include <unistd.h>
#include <zlib.h>
+#include <cstdio>
#include <iostream>
#include <string>
@@ -44,6 +45,7 @@
#include "base/random.hh"
#include "base/types.hh"
#include "config/full_system.hh"
+#include "config/the_isa.hh"
#include "mem/packet_access.hh"
#include "mem/physical.hh"
#include "sim/eventq.hh"
diff --git a/src/mem/port_impl.hh b/src/mem/port_impl.hh
index 989cfd338..bc9592164 100644
--- a/src/mem/port_impl.hh
+++ b/src/mem/port_impl.hh
@@ -28,9 +28,8 @@
* Authors: Ali Saidi
*/
-//To get endianness
#include "arch/isa_traits.hh"
-
+#include "config/the_isa.hh"
#include "mem/port.hh"
#include "sim/byteswap.hh"
diff --git a/src/mem/protocol/MI_example-dir.sm b/src/mem/protocol/MI_example-dir.sm
index 17f39af5b..1f64d25df 100644
--- a/src/mem/protocol/MI_example-dir.sm
+++ b/src/mem/protocol/MI_example-dir.sm
@@ -1,8 +1,6 @@
machine(Directory, "Directory protocol")
-: int directory_latency,
- int dma_select_low_bit,
- int dma_select_num_bits
+: int directory_latency
{
MessageBuffer forwardFromDir, network="To", virtual_network="2", ordered="false";
@@ -74,6 +72,7 @@ machine(Directory, "Directory protocol")
State TBEState, desc="Transient State";
DataBlock DataBlk, desc="Data to be written (DMA write only)";
int Len, desc="...";
+ MachineID DmaRequestor, desc="DMA requestor";
}
external_type(TBETable) {
@@ -243,8 +242,7 @@ machine(Directory, "Directory protocol")
out_msg.LineAddress := address;
out_msg.Type := DMAResponseType:DATA;
out_msg.DataBlk := in_msg.DataBlk; // we send the entire data block and rely on the dma controller to split it up if need be
- out_msg.Destination.add(mapAddressToRange(address, MachineType:DMA,
- dma_select_low_bit, dma_select_num_bits));
+ out_msg.Destination.add(TBEs[address].DmaRequestor);
out_msg.MessageSize := MessageSizeType:Response_Data;
}
}
@@ -259,8 +257,7 @@ machine(Directory, "Directory protocol")
out_msg.LineAddress := address;
out_msg.Type := DMAResponseType:DATA;
out_msg.DataBlk := in_msg.DataBlk; // we send the entire data block and rely on the dma controller to split it up if need be
- out_msg.Destination.add(mapAddressToRange(address, MachineType:DMA,
- dma_select_low_bit, dma_select_num_bits));
+ out_msg.Destination.add(TBEs[address].DmaRequestor);
out_msg.MessageSize := MessageSizeType:Response_Data;
}
}
@@ -271,8 +268,7 @@ machine(Directory, "Directory protocol")
out_msg.PhysicalAddress := address;
out_msg.LineAddress := address;
out_msg.Type := DMAResponseType:ACK;
- out_msg.Destination.add(mapAddressToRange(address, MachineType:DMA,
- dma_select_low_bit, dma_select_num_bits));
+ out_msg.Destination.add(TBEs[address].DmaRequestor);
out_msg.MessageSize := MessageSizeType:Writeback_Control;
}
}
@@ -343,6 +339,14 @@ machine(Directory, "Directory protocol")
TBEs[address].DataBlk := in_msg.DataBlk;
TBEs[address].PhysicalAddress := in_msg.PhysicalAddress;
TBEs[address].Len := in_msg.Len;
+ TBEs[address].DmaRequestor := in_msg.Requestor;
+ }
+ }
+
+ action(r_allocateTbeForDmaRead, "\r", desc="Allocate TBE for DMA Read") {
+ peek(dmaRequestQueue_in, DMARequestMsg) {
+ TBEs.allocate(address);
+ TBEs[address].DmaRequestor := in_msg.Requestor;
}
}
@@ -485,6 +489,7 @@ machine(Directory, "Directory protocol")
transition(I, DMA_READ, ID) {
//dr_sendDMAData;
+ r_allocateTbeForDmaRead;
qf_queueMemoryFetchRequestDMA;
p_popIncomingDMARequestQueue;
}
@@ -492,6 +497,7 @@ machine(Directory, "Directory protocol")
transition(ID, Memory_Data, I) {
dr_sendDMAData;
//p_popIncomingDMARequestQueue;
+ w_deallocateTBE;
l_popMemQueue;
}
diff --git a/src/mem/protocol/MI_example-dma.sm b/src/mem/protocol/MI_example-dma.sm
index e883288df..79c42e719 100644
--- a/src/mem/protocol/MI_example-dma.sm
+++ b/src/mem/protocol/MI_example-dma.sm
@@ -71,6 +71,7 @@ machine(DMA, "DMA Controller")
out_msg.PhysicalAddress := in_msg.PhysicalAddress;
out_msg.LineAddress := in_msg.LineAddress;
out_msg.Type := DMARequestType:READ;
+ out_msg.Requestor := machineID;
out_msg.DataBlk := in_msg.DataBlk;
out_msg.Len := in_msg.Len;
out_msg.Destination.add(map_Address_to_Directory(address));
@@ -85,6 +86,7 @@ machine(DMA, "DMA Controller")
out_msg.PhysicalAddress := in_msg.PhysicalAddress;
out_msg.LineAddress := in_msg.LineAddress;
out_msg.Type := DMARequestType:WRITE;
+ out_msg.Requestor := machineID;
out_msg.DataBlk := in_msg.DataBlk;
out_msg.Len := in_msg.Len;
out_msg.Destination.add(map_Address_to_Directory(address));
@@ -113,10 +115,6 @@ machine(DMA, "DMA Controller")
dmaResponseQueue_in.dequeue();
}
- action(z_stall, "z", desc="dma is busy..stall") {
- // do nothing
- }
-
transition(READY, ReadRequest, BUSY_RD) {
s_sendReadRequest;
p_popRequestQueue;
diff --git a/src/mem/protocol/MI_example-msg.sm b/src/mem/protocol/MI_example-msg.sm
index d4d557200..3cdb74e49 100644
--- a/src/mem/protocol/MI_example-msg.sm
+++ b/src/mem/protocol/MI_example-msg.sm
@@ -105,6 +105,7 @@ structure(DMARequestMsg, desc="...", interface="NetworkMessage") {
DMARequestType Type, desc="Request type (read/write)";
Address PhysicalAddress, desc="Physical address for this request";
Address LineAddress, desc="Line address for this request";
+ MachineID Requestor, desc="Node who initiated the request";
NetDest Destination, desc="Destination";
DataBlock DataBlk, desc="DataBlk attached to this request";
int Len, desc="The length of the request";
diff --git a/src/mem/protocol/MOESI_CMP_token-L1cache.sm b/src/mem/protocol/MOESI_CMP_token-L1cache.sm
index ab58c5c00..3fb4a8862 100644
--- a/src/mem/protocol/MOESI_CMP_token-L1cache.sm
+++ b/src/mem/protocol/MOESI_CMP_token-L1cache.sm
@@ -32,21 +32,32 @@
*
*/
-machine(L1Cache, "Token protocol") {
+machine(L1Cache, "Token protocol")
+ : int l1_request_latency,
+ int l1_response_latency,
+ int l2_select_low_bit,
+ int l2_select_num_bits,
+ int N_tokens,
+ int retry_threshold,
+ int fixed_timeout_latency,
+ bool dynamic_timeout_enabled
+{
// From this node's L1 cache TO the network
- // a local L1 -> this L2 bank, currently ordered with directory forwarded requests
- MessageBuffer requestFromL1Cache, network="To", virtual_network="0", ordered="false";
+
// a local L1 -> this L2 bank
- MessageBuffer responseFromL1Cache, network="To", virtual_network="2", ordered="false";
- MessageBuffer persistentFromL1Cache, network="To", virtual_network="3", ordered="true";
+ MessageBuffer responseFromL1Cache, network="To", virtual_network="1", ordered="false";
+ MessageBuffer persistentFromL1Cache, network="To", virtual_network="2", ordered="true";
+ // a local L1 -> this L2 bank, currently ordered with directory forwarded requests
+ MessageBuffer requestFromL1Cache, network="To", virtual_network="4", ordered="false";
+
// To this node's L1 cache FROM the network
// a L2 bank -> this L1
- MessageBuffer requestToL1Cache, network="From", virtual_network="0", ordered="false";
+ MessageBuffer responseToL1Cache, network="From", virtual_network="1", ordered="false";
+ MessageBuffer persistentToL1Cache, network="From", virtual_network="2", ordered="true";
// a L2 bank -> this L1
- MessageBuffer responseToL1Cache, network="From", virtual_network="2", ordered="false";
- MessageBuffer persistentToL1Cache, network="From", virtual_network="3", ordered="true";
+ MessageBuffer requestToL1Cache, network="From", virtual_network="4", ordered="false";
// STATES
enumeration(State, desc="Cache states", default="L1Cache_State_I") {
@@ -111,10 +122,6 @@ machine(L1Cache, "Token protocol") {
// TYPES
- int getRetryThreshold();
- int getFixedTimeoutLatency();
- bool getDynamicTimeoutEnabled();
-
// CacheEntry
structure(Entry, desc="...", interface="AbstractCacheEntry") {
State CacheState, desc="cache state";
@@ -143,7 +150,7 @@ machine(L1Cache, "Token protocol") {
external_type(CacheMemory) {
bool cacheAvail(Address);
Address cacheProbe(Address);
- void allocate(Address);
+ void allocate(Address, Entry);
void deallocate(Address);
Entry lookup(Address);
void changePermission(Address, AccessPermission);
@@ -157,17 +164,28 @@ machine(L1Cache, "Token protocol") {
bool isPresent(Address);
}
+ external_type(PersistentTable) {
+ void persistentRequestLock(Address, MachineID, AccessType);
+ void persistentRequestUnlock(Address, MachineID);
+ bool okToIssueStarving(Address, MachineID);
+ MachineID findSmallest(Address);
+ AccessType typeOfSmallest(Address);
+ void markEntries(Address);
+ bool isLocked(Address);
+ int countStarvingForAddress(Address);
+ int countReadStarvingForAddress(Address);
+ }
TBETable L1_TBEs, template_hack="<L1Cache_TBE>";
- CacheMemory L1IcacheMemory, template_hack="<L1Cache_Entry>", constructor_hack='L1_CACHE_NUM_SETS_BITS,L1_CACHE_ASSOC,MachineType_L1Cache,int_to_string(i)+"_L1I"', abstract_chip_ptr="true";
- CacheMemory L1DcacheMemory, template_hack="<L1Cache_Entry>", constructor_hack='L1_CACHE_NUM_SETS_BITS,L1_CACHE_ASSOC,MachineType_L1Cache,int_to_string(i)+"_L1D"', abstract_chip_ptr="true";
+ CacheMemory L1IcacheMemory, factory='RubySystem::getCache(m_cfg["icache"])';
+ CacheMemory L1DcacheMemory, factory='RubySystem::getCache(m_cfg["dcache"])';
MessageBuffer mandatoryQueue, ordered="false", abstract_chip_ptr="true";
- Sequencer sequencer, abstract_chip_ptr="true", constructor_hack="i";
+ Sequencer sequencer, factory='RubySystem::getSequencer(m_cfg["sequencer"])';
bool starving, default="false";
- PersistentTable persistentTable, constructor_hack="i";
+ PersistentTable persistentTable;
TimerTable useTimerTable;
TimerTable reissueTimerTable;
@@ -175,11 +193,11 @@ machine(L1Cache, "Token protocol") {
int outstandingPersistentRequests, default="0";
int averageLatencyHysteresis, default="(8)"; // Constant that provides hysteresis for calculated the estimated average
- int averageLatencyCounter, default="(500 << (*m_L1Cache_averageLatencyHysteresis_vec[i]))";
+ int averageLatencyCounter, default="(500 << (*m_L1Cache_averageLatencyHysteresis_ptr))";
int averageLatencyEstimate() {
DEBUG_EXPR( (averageLatencyCounter >> averageLatencyHysteresis) );
- profile_average_latency_estimate( (averageLatencyCounter >> averageLatencyHysteresis) );
+ //profile_average_latency_estimate( (averageLatencyCounter >> averageLatencyHysteresis) );
return averageLatencyCounter >> averageLatencyHysteresis;
}
@@ -366,30 +384,33 @@ machine(L1Cache, "Token protocol") {
}
}
- GenericMachineType getNondirectHitMachType(Address addr, MachineID sender) {
- if (machineIDToMachineType(sender) == MachineType:L1Cache) {
- return GenericMachineType:L1Cache_wCC; // NOTE direct L1 hits should not call this
- } else if (machineIDToMachineType(sender) == MachineType:L2Cache) {
- if ( sender == (map_L1CacheMachId_to_L2Cache(addr,machineID))) {
- return GenericMachineType:L2Cache;
- } else {
- return GenericMachineType:L2Cache_wCC;
- }
- } else {
- return ConvertMachToGenericMach(machineIDToMachineType(sender));
- }
- }
-
- bool okToIssueStarving(Address addr) {
- return persistentTable.okToIssueStarving(addr);
+// GenericMachineType getNondirectHitMachType(Address addr, MachineID sender) {
+// if (machineIDToMachineType(sender) == MachineType:L1Cache) {
+// return GenericMachineType:L1Cache_wCC; // NOTE direct L1 hits should not call this
+// } else if (machineIDToMachineType(sender) == MachineType:L2Cache) {
+//
+// if (sender == (mapAddressToRange(addr,
+// MachineType:L2Cache,
+// l2_select_low_bit,
+// l2_select_num_bits))) {
+//
+// return GenericMachineType:L2Cache;
+// } else {
+// return GenericMachineType:L2Cache_wCC;
+// }
+// } else {
+// return ConvertMachToGenericMach(machineIDToMachineType(sender));
+// }
+// }
+
+ bool okToIssueStarving(Address addr, MachineID machinID) {
+ return persistentTable.okToIssueStarving(addr, machineID);
}
void markPersistentEntries(Address addr) {
persistentTable.markEntries(addr);
}
- MessageBuffer triggerQueue, ordered="false", random="false";
-
// ** OUT_PORTS **
out_port(persistentNetwork_out, PersistentMsg, persistentFromL1Cache);
out_port(requestNetwork_out, RequestMsg, requestFromL1Cache);
@@ -507,7 +528,11 @@ machine(L1Cache, "Token protocol") {
// Mark TBE flag if response received off-chip. Use this to update average latency estimate
if ( in_msg.SenderMachine == MachineType:L2Cache ) {
- if (in_msg.Sender == map_L1CacheMachId_to_L2Cache(in_msg.Address, machineID)) {
+ if (in_msg.Sender == mapAddressToRange(in_msg.Address,
+ MachineType:L2Cache,
+ l2_select_low_bit,
+ l2_select_num_bits)) {
+
// came from an off-chip L2 cache
if (L1_TBEs.isPresent(in_msg.Address)) {
// L1_TBEs[in_msg.Address].ExternalResponse := true;
@@ -523,15 +548,15 @@ machine(L1Cache, "Token protocol") {
// profile_memory_response( in_msg.Address);
}
} else if ( in_msg.SenderMachine == MachineType:L1Cache) {
- if (isLocalProcessor(machineID, in_msg.Sender) == false) {
- if (L1_TBEs.isPresent(in_msg.Address)) {
+ //if (isLocalProcessor(machineID, in_msg.Sender) == false) {
+ //if (L1_TBEs.isPresent(in_msg.Address)) {
// L1_TBEs[in_msg.Address].ExternalResponse := true;
// profile_offchipL1_response(in_msg.Address );
- }
- }
- else {
+ //}
+ //}
+ //else {
// profile_onchipL1_response(in_msg.Address );
- }
+ //}
} else {
error("unexpected SenderMachine");
}
@@ -570,42 +595,42 @@ machine(L1Cache, "Token protocol") {
// ** INSTRUCTION ACCESS ***
// Check to see if it is in the OTHER L1
- if (L1DcacheMemory.isTagPresent(in_msg.Address)) {
+ if (L1DcacheMemory.isTagPresent(in_msg.LineAddress)) {
// The block is in the wrong L1, try to write it to the L2
- trigger(Event:L1_Replacement, in_msg.Address);
+ trigger(Event:L1_Replacement, in_msg.LineAddress);
}
- if (L1IcacheMemory.isTagPresent(in_msg.Address)) {
+ if (L1IcacheMemory.isTagPresent(in_msg.LineAddress)) {
// The tag matches for the L1, so the L1 fetches the line. We know it can't be in the L2 due to exclusion
- trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address);
+ trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress);
} else {
- if (L1IcacheMemory.cacheAvail(in_msg.Address)) {
+ if (L1IcacheMemory.cacheAvail(in_msg.LineAddress)) {
// L1 does't have the line, but we have space for it in the L1
- trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address);
+ trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress);
} else {
// No room in the L1, so we need to make room
- trigger(Event:L1_Replacement, L1IcacheMemory.cacheProbe(in_msg.Address));
+ trigger(Event:L1_Replacement, L1IcacheMemory.cacheProbe(in_msg.LineAddress));
}
}
} else {
// *** DATA ACCESS ***
// Check to see if it is in the OTHER L1
- if (L1IcacheMemory.isTagPresent(in_msg.Address)) {
+ if (L1IcacheMemory.isTagPresent(in_msg.LineAddress)) {
// The block is in the wrong L1, try to write it to the L2
- trigger(Event:L1_Replacement, in_msg.Address);
+ trigger(Event:L1_Replacement, in_msg.LineAddress);
}
- if (L1DcacheMemory.isTagPresent(in_msg.Address)) {
+ if (L1DcacheMemory.isTagPresent(in_msg.LineAddress)) {
// The tag matches for the L1, so the L1 fetches the line. We know it can't be in the L2 due to exclusion
- trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address);
+ trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress);
} else {
- if (L1DcacheMemory.cacheAvail(in_msg.Address)) {
+ if (L1DcacheMemory.cacheAvail(in_msg.LineAddress)) {
// L1 does't have the line, but we have space for it in the L1
- trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.Address);
+ trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress);
} else {
// No room in the L1, so we need to make room
- trigger(Event:L1_Replacement, L1DcacheMemory.cacheProbe(in_msg.Address));
+ trigger(Event:L1_Replacement, L1DcacheMemory.cacheProbe(in_msg.LineAddress));
}
}
}
@@ -618,19 +643,31 @@ machine(L1Cache, "Token protocol") {
action(a_issueReadRequest, "a", desc="Issue GETS") {
if (L1_TBEs[address].IssueCount == 0) {
// Update outstanding requests
- profile_outstanding_request(outstandingRequests);
+ //profile_outstanding_request(outstandingRequests);
outstandingRequests := outstandingRequests + 1;
}
- if (L1_TBEs[address].IssueCount >= getRetryThreshold() ) {
+ if (L1_TBEs[address].IssueCount >= retry_threshold) {
// Issue a persistent request if possible
- if (okToIssueStarving(address) && (starving == false)) {
- enqueue(persistentNetwork_out, PersistentMsg, latency="L1_REQUEST_LATENCY") {
+ if (okToIssueStarving(address, machineID) && (starving == false)) {
+ enqueue(persistentNetwork_out, PersistentMsg, latency = l1_request_latency) {
out_msg.Address := address;
out_msg.Type := PersistentRequestType:GETS_PERSISTENT;
out_msg.Requestor := machineID;
out_msg.Destination.broadcast(MachineType:L1Cache);
- out_msg.Destination.addNetDest(getAllPertinentL2Banks(address));
+
+ //
+ // Currently the configuration system limits the system to only one
+ // chip. Therefore, if we assume one shared L2 cache, then only one
+ // pertinent L2 cache exist.
+ //
+ //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address));
+
+ out_msg.Destination.add(mapAddressToRange(address,
+ MachineType:L2Cache,
+ l2_select_low_bit,
+ l2_select_num_bits));
+
out_msg.Destination.add(map_Address_to_Directory(address));
out_msg.MessageSize := MessageSizeType:Persistent_Control;
out_msg.Prefetch := L1_TBEs[address].Prefetch;
@@ -640,11 +677,11 @@ machine(L1Cache, "Token protocol") {
starving := true;
if (L1_TBEs[address].IssueCount == 0) {
- profile_persistent_prediction(address, L1_TBEs[address].AccessType);
+ //profile_persistent_prediction(address, L1_TBEs[address].AccessType);
}
// Update outstanding requests
- profile_outstanding_persistent_request(outstandingPersistentRequests);
+ //profile_outstanding_persistent_request(outstandingPersistentRequests);
outstandingPersistentRequests := outstandingPersistentRequests + 1;
// Increment IssueCount
@@ -666,11 +703,16 @@ machine(L1Cache, "Token protocol") {
}
} else {
// Make a normal request
- enqueue(requestNetwork_out, RequestMsg, latency="L1_REQUEST_LATENCY") {
+ enqueue(requestNetwork_out, RequestMsg, latency = l1_request_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceRequestType:GETS;
out_msg.Requestor := machineID;
- out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address,machineID));
+
+ out_msg.Destination.add(mapAddressToRange(address,
+ MachineType:L2Cache,
+ l2_select_low_bit,
+ l2_select_num_bits));
+
out_msg.RetryNum := L1_TBEs[address].IssueCount;
if (L1_TBEs[address].IssueCount == 0) {
out_msg.MessageSize := MessageSizeType:Request_Control;
@@ -682,11 +724,18 @@ machine(L1Cache, "Token protocol") {
}
// send to other local L1s, with local bit set
- enqueue(requestNetwork_out, RequestMsg, latency="L1_REQUEST_LATENCY") {
+ enqueue(requestNetwork_out, RequestMsg, latency = l1_request_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceRequestType:GETS;
out_msg.Requestor := machineID;
- out_msg.Destination := getOtherLocalL1IDs(machineID);
+
+ //
+ // Since only one chip, assuming all L1 caches are local
+ //
+ //out_msg.Destination := getOtherLocalL1IDs(machineID);
+ out_msg.Destination.broadcast(MachineType:L1Cache);
+ out_msg.Destination.remove(machineID);
+
out_msg.RetryNum := L1_TBEs[address].IssueCount;
out_msg.isLocal := true;
if (L1_TBEs[address].IssueCount == 0) {
@@ -703,10 +752,10 @@ machine(L1Cache, "Token protocol") {
// Set a wakeup timer
- if (getDynamicTimeoutEnabled()) {
+ if (dynamic_timeout_enabled) {
reissueTimerTable.set(address, 1.25 * averageLatencyEstimate());
} else {
- reissueTimerTable.set(address, getFixedTimeoutLatency());
+ reissueTimerTable.set(address, fixed_timeout_latency);
}
}
@@ -716,20 +765,32 @@ machine(L1Cache, "Token protocol") {
if (L1_TBEs[address].IssueCount == 0) {
// Update outstanding requests
- profile_outstanding_request(outstandingRequests);
+ //profile_outstanding_request(outstandingRequests);
outstandingRequests := outstandingRequests + 1;
}
- if (L1_TBEs[address].IssueCount >= getRetryThreshold() ) {
+ if (L1_TBEs[address].IssueCount >= retry_threshold) {
// Issue a persistent request if possible
- if ( okToIssueStarving(address) && (starving == false)) {
- enqueue(persistentNetwork_out, PersistentMsg, latency="L1_REQUEST_LATENCY") {
+ if ( okToIssueStarving(address, machineID) && (starving == false)) {
+ enqueue(persistentNetwork_out, PersistentMsg, latency = l1_request_latency) {
out_msg.Address := address;
out_msg.Type := PersistentRequestType:GETX_PERSISTENT;
out_msg.Requestor := machineID;
out_msg.RequestorMachine := MachineType:L1Cache;
out_msg.Destination.broadcast(MachineType:L1Cache);
- out_msg.Destination.addNetDest(getAllPertinentL2Banks(address));
+
+ //
+ // Currently the configuration system limits the system to only one
+ // chip. Therefore, if we assume one shared L2 cache, then only one
+ // pertinent L2 cache exist.
+ //
+ //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address));
+
+ out_msg.Destination.add(mapAddressToRange(address,
+ MachineType:L2Cache,
+ l2_select_low_bit,
+ l2_select_num_bits));
+
out_msg.Destination.add(map_Address_to_Directory(address));
out_msg.MessageSize := MessageSizeType:Persistent_Control;
out_msg.Prefetch := L1_TBEs[address].Prefetch;
@@ -739,11 +800,11 @@ machine(L1Cache, "Token protocol") {
starving := true;
// Update outstanding requests
- profile_outstanding_persistent_request(outstandingPersistentRequests);
+ //profile_outstanding_persistent_request(outstandingPersistentRequests);
outstandingPersistentRequests := outstandingPersistentRequests + 1;
if (L1_TBEs[address].IssueCount == 0) {
- profile_persistent_prediction(address, L1_TBEs[address].AccessType);
+ //profile_persistent_prediction(address, L1_TBEs[address].AccessType);
}
// Increment IssueCount
@@ -766,12 +827,17 @@ machine(L1Cache, "Token protocol") {
} else {
// Make a normal request
- enqueue(requestNetwork_out, RequestMsg, latency="L1_REQUEST_LATENCY") {
+ enqueue(requestNetwork_out, RequestMsg, latency = l1_request_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceRequestType:GETX;
out_msg.Requestor := machineID;
out_msg.RequestorMachine := MachineType:L1Cache;
- out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address,machineID));
+
+ out_msg.Destination.add(mapAddressToRange(address,
+ MachineType:L2Cache,
+ l2_select_low_bit,
+ l2_select_num_bits));
+
out_msg.RetryNum := L1_TBEs[address].IssueCount;
if (L1_TBEs[address].IssueCount == 0) {
@@ -784,12 +850,19 @@ machine(L1Cache, "Token protocol") {
}
// send to other local L1s too
- enqueue(requestNetwork_out, RequestMsg, latency="L1_REQUEST_LATENCY") {
+ enqueue(requestNetwork_out, RequestMsg, latency = l1_request_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceRequestType:GETX;
out_msg.Requestor := machineID;
out_msg.isLocal := true;
- out_msg.Destination := getOtherLocalL1IDs(machineID);
+
+ //
+ // Since only one chip, assuming all L1 caches are local
+ //
+ //out_msg.Destination := getOtherLocalL1IDs(machineID);
+ out_msg.Destination.broadcast(MachineType:L1Cache);
+ out_msg.Destination.remove(machineID);
+
out_msg.RetryNum := L1_TBEs[address].IssueCount;
if (L1_TBEs[address].IssueCount == 0) {
out_msg.MessageSize := MessageSizeType:Request_Control;
@@ -807,10 +880,10 @@ machine(L1Cache, "Token protocol") {
DEBUG_EXPR(L1_TBEs[address].IssueCount);
// Set a wakeup timer
- if (getDynamicTimeoutEnabled()) {
+ if (dynamic_timeout_enabled) {
reissueTimerTable.set(address, 1.25 * averageLatencyEstimate());
} else {
- reissueTimerTable.set(address, getFixedTimeoutLatency());
+ reissueTimerTable.set(address, fixed_timeout_latency);
}
}
}
@@ -818,7 +891,7 @@ machine(L1Cache, "Token protocol") {
action(bb_bounceResponse, "\b", desc="Bounce tokens and data to memory") {
peek(responseNetwork_in, ResponseMsg) {
// FIXME, should use a 3rd vnet
- enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency="1") {
out_msg.Address := address;
out_msg.Type := in_msg.Type;
out_msg.Sender := machineID;
@@ -833,11 +906,16 @@ machine(L1Cache, "Token protocol") {
}
action(c_ownedReplacement, "c", desc="Issue writeback") {
- enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) {
out_msg.Address := address;
out_msg.Sender := machineID;
out_msg.SenderMachine := MachineType:L1Cache;
- out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address,machineID));
+
+ out_msg.Destination.add(mapAddressToRange(address,
+ MachineType:L2Cache,
+ l2_select_low_bit,
+ l2_select_num_bits));
+
out_msg.Tokens := getCacheEntry(address).Tokens;
out_msg.DataBlk := getCacheEntry(address).DataBlk;
out_msg.Dirty := getCacheEntry(address).Dirty;
@@ -853,11 +931,16 @@ machine(L1Cache, "Token protocol") {
// don't send writeback if replacing block with no tokens
if (getCacheEntry(address).Tokens != 0) {
- enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) {
out_msg.Address := address;
out_msg.Sender := machineID;
out_msg.SenderMachine := MachineType:L1Cache;
- out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address,machineID));
+
+ out_msg.Destination.add(mapAddressToRange(address,
+ MachineType:L2Cache,
+ l2_select_low_bit,
+ l2_select_num_bits));
+
out_msg.Tokens := getCacheEntry(address).Tokens;
out_msg.DataBlk := getCacheEntry(address).DataBlk;
// assert(getCacheEntry(address).Dirty == false);
@@ -879,7 +962,7 @@ machine(L1Cache, "Token protocol") {
action(d_sendDataWithToken, "d", desc="Send data and a token from cache to requestor") {
peek(requestNetwork_in, RequestMsg) {
- enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:DATA_SHARED;
out_msg.Sender := machineID;
@@ -902,14 +985,14 @@ machine(L1Cache, "Token protocol") {
action(d_sendDataWithNTokenIfAvail, "\dd", desc="Send data and a token from cache to requestor") {
peek(requestNetwork_in, RequestMsg) {
- if (getCacheEntry(address).Tokens > N_tokens()) {
- enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") {
+ if (getCacheEntry(address).Tokens > N_tokens) {
+ enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:DATA_SHARED;
out_msg.Sender := machineID;
out_msg.SenderMachine := MachineType:L1Cache;
out_msg.Destination.add(in_msg.Requestor);
- out_msg.Tokens := N_tokens();
+ out_msg.Tokens := N_tokens;
out_msg.DataBlk := getCacheEntry(address).DataBlk;
// out_msg.Dirty := getCacheEntry(address).Dirty;
out_msg.Dirty := false;
@@ -919,10 +1002,10 @@ machine(L1Cache, "Token protocol") {
out_msg.MessageSize := MessageSizeType:Response_Data;
}
}
- getCacheEntry(address).Tokens := getCacheEntry(address).Tokens - N_tokens();
+ getCacheEntry(address).Tokens := getCacheEntry(address).Tokens - N_tokens;
}
else if (getCacheEntry(address).Tokens > 1) {
- enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:DATA_SHARED;
out_msg.Sender := machineID;
@@ -946,7 +1029,7 @@ machine(L1Cache, "Token protocol") {
action(dd_sendDataWithAllTokens, "\d", desc="Send data and all tokens from cache to requestor") {
peek(requestNetwork_in, RequestMsg) {
- enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:DATA_OWNER;
out_msg.Sender := machineID;
@@ -969,7 +1052,7 @@ machine(L1Cache, "Token protocol") {
action(e_sendAckWithCollectedTokens, "e", desc="Send ack with the tokens we've collected thus far.") {
// assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself
if (getCacheEntry(address).Tokens > 0) {
- enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:ACK;
out_msg.Sender := machineID;
@@ -986,7 +1069,7 @@ machine(L1Cache, "Token protocol") {
action(ee_sendDataWithAllTokens, "\e", desc="Send data and all tokens from cache to starver") {
//assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself
assert(getCacheEntry(address).Tokens > 0);
- enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:DATA_OWNER;
out_msg.Sender := machineID;
@@ -1005,23 +1088,23 @@ machine(L1Cache, "Token protocol") {
//assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself
assert(getCacheEntry(address).Tokens > 0);
if (getCacheEntry(address).Tokens > 1) {
- enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:ACK;
out_msg.Sender := machineID;
out_msg.SenderMachine := MachineType:L1Cache;
out_msg.Destination.add(persistentTable.findSmallest(address));
assert(getCacheEntry(address).Tokens >= 1);
- if (getCacheEntry(address).Tokens > N_tokens()) {
- out_msg.Tokens := getCacheEntry(address).Tokens - N_tokens();
+ if (getCacheEntry(address).Tokens > N_tokens) {
+ out_msg.Tokens := getCacheEntry(address).Tokens - N_tokens;
} else {
out_msg.Tokens := getCacheEntry(address).Tokens - 1;
}
out_msg.MessageSize := MessageSizeType:Response_Control;
}
}
- if (getCacheEntry(address).Tokens > N_tokens()) {
- getCacheEntry(address).Tokens := N_tokens();
+ if (getCacheEntry(address).Tokens > N_tokens) {
+ getCacheEntry(address).Tokens := N_tokens;
} else {
getCacheEntry(address).Tokens := 1;
}
@@ -1031,15 +1114,15 @@ machine(L1Cache, "Token protocol") {
//assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself
assert(getCacheEntry(address).Tokens > 0);
if (getCacheEntry(address).Tokens > 1) {
- enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:DATA_OWNER;
out_msg.Sender := machineID;
out_msg.SenderMachine := MachineType:L1Cache;
out_msg.Destination.add(persistentTable.findSmallest(address));
assert(getCacheEntry(address).Tokens >= 1);
- if (getCacheEntry(address).Tokens > N_tokens()) {
- out_msg.Tokens := getCacheEntry(address).Tokens - N_tokens();
+ if (getCacheEntry(address).Tokens > N_tokens) {
+ out_msg.Tokens := getCacheEntry(address).Tokens - N_tokens;
} else {
out_msg.Tokens := getCacheEntry(address).Tokens - 1;
}
@@ -1047,8 +1130,8 @@ machine(L1Cache, "Token protocol") {
out_msg.Dirty := getCacheEntry(address).Dirty;
out_msg.MessageSize := MessageSizeType:Response_Data;
}
- if (getCacheEntry(address).Tokens > N_tokens()) {
- getCacheEntry(address).Tokens := N_tokens();
+ if (getCacheEntry(address).Tokens > N_tokens) {
+ getCacheEntry(address).Tokens := N_tokens;
} else {
getCacheEntry(address).Tokens := 1;
}
@@ -1061,7 +1144,7 @@ machine(L1Cache, "Token protocol") {
peek(responseNetwork_in, ResponseMsg) {
// assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself
// FIXME, should use a 3rd vnet in some cases
- enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency="1") {
out_msg.Address := address;
out_msg.Type := in_msg.Type;
out_msg.Sender := machineID;
@@ -1079,7 +1162,8 @@ machine(L1Cache, "Token protocol") {
action(h_load_hit, "h", desc="Notify sequencer the load completed.") {
DEBUG_EXPR(address);
DEBUG_EXPR(getCacheEntry(address).DataBlk);
- sequencer.readCallback(address, getCacheEntry(address).DataBlk, GenericMachineType:L1Cache, PrefetchBit:No);
+ //sequencer.readCallback(address, getCacheEntry(address).DataBlk, GenericMachineType:L1Cache, PrefetchBit:No);
+ sequencer.readCallback(address, getCacheEntry(address).DataBlk);
}
action(x_external_load_hit, "x", desc="Notify sequencer the load completed.") {
@@ -1087,14 +1171,16 @@ machine(L1Cache, "Token protocol") {
DEBUG_EXPR(getCacheEntry(address).DataBlk);
peek(responseNetwork_in, ResponseMsg) {
- sequencer.readCallback(address, getCacheEntry(address).DataBlk, getNondirectHitMachType(in_msg.Address, in_msg.Sender), PrefetchBit:No);
+ //sequencer.readCallback(address, getCacheEntry(address).DataBlk, getNondirectHitMachType(in_msg.Address, in_msg.Sender), PrefetchBit:No);
+ sequencer.readCallback(address, getCacheEntry(address).DataBlk);
}
}
action(hh_store_hit, "\h", desc="Notify sequencer that store completed.") {
DEBUG_EXPR(address);
DEBUG_EXPR(getCacheEntry(address).DataBlk);
- sequencer.writeCallback(address, getCacheEntry(address).DataBlk, GenericMachineType:L1Cache, PrefetchBit:No);
+ //sequencer.writeCallback(address, getCacheEntry(address).DataBlk, GenericMachineType:L1Cache, PrefetchBit:No);
+ sequencer.writeCallback(address, getCacheEntry(address).DataBlk);
getCacheEntry(address).Dirty := true;
DEBUG_EXPR(getCacheEntry(address).DataBlk);
}
@@ -1103,7 +1189,8 @@ machine(L1Cache, "Token protocol") {
DEBUG_EXPR(address);
DEBUG_EXPR(getCacheEntry(address).DataBlk);
peek(responseNetwork_in, ResponseMsg) {
- sequencer.writeCallback(address, getCacheEntry(address).DataBlk, getNondirectHitMachType(in_msg.Address, in_msg.Sender), PrefetchBit:No);
+ //sequencer.writeCallback(address, getCacheEntry(address).DataBlk, getNondirectHitMachType(in_msg.Address, in_msg.Sender), PrefetchBit:No);
+ sequencer.writeCallback(address, getCacheEntry(address).DataBlk);
}
getCacheEntry(address).Dirty := true;
DEBUG_EXPR(getCacheEntry(address).DataBlk);
@@ -1133,8 +1220,6 @@ machine(L1Cache, "Token protocol") {
useTimerTable.unset(address);
}
-
-
action(k_popMandatoryQueue, "k", desc="Pop mandatory queue.") {
mandatoryQueue_in.dequeue();
}
@@ -1156,14 +1241,19 @@ machine(L1Cache, "Token protocol") {
}
action(p_informL2AboutTokenLoss, "p", desc="Inform L2 about loss of all tokens") {
- enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:INV;
out_msg.Tokens := 0;
out_msg.Sender := machineID;
out_msg.SenderMachine := MachineType:L1Cache;
out_msg.DestMachine := MachineType:L2Cache;
- out_msg.Destination.add(map_L1CacheMachId_to_L2Cache(address,machineID));
+
+ out_msg.Destination.add(mapAddressToRange(address,
+ MachineType:L2Cache,
+ l2_select_low_bit,
+ l2_select_num_bits));
+
out_msg.MessageSize := MessageSizeType:Response_Control;
}
}
@@ -1189,13 +1279,25 @@ machine(L1Cache, "Token protocol") {
if (L1_TBEs[address].WentPersistent) {
// assert(starving == true);
outstandingRequests := outstandingRequests - 1;
- enqueue(persistentNetwork_out, PersistentMsg, latency="L1_REQUEST_LATENCY") {
+ enqueue(persistentNetwork_out, PersistentMsg, latency = l1_request_latency) {
out_msg.Address := address;
out_msg.Type := PersistentRequestType:DEACTIVATE_PERSISTENT;
out_msg.Requestor := machineID;
out_msg.RequestorMachine := MachineType:L1Cache;
out_msg.Destination.broadcast(MachineType:L1Cache);
- out_msg.Destination.addNetDest(getAllPertinentL2Banks(address));
+
+ //
+ // Currently the configuration system limits the system to only one
+ // chip. Therefore, if we assume one shared L2 cache, then only one
+ // pertinent L2 cache exist.
+ //
+ //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address));
+
+ out_msg.Destination.add(mapAddressToRange(address,
+ MachineType:L2Cache,
+ l2_select_low_bit,
+ l2_select_num_bits));
+
out_msg.Destination.add(map_Address_to_Directory(address));
out_msg.MessageSize := MessageSizeType:Persistent_Control;
}
@@ -1217,14 +1319,14 @@ machine(L1Cache, "Token protocol") {
// profile_token_retry(address, L1_TBEs[address].AccessType, 1);
//}
- profile_token_retry(address, L1_TBEs[address].AccessType, L1_TBEs[address].IssueCount);
+ //profile_token_retry(address, L1_TBEs[address].AccessType, L1_TBEs[address].IssueCount);
L1_TBEs.deallocate(address);
}
action(t_sendAckWithCollectedTokens, "t", desc="Send ack with the tokens we've collected thus far.") {
if (getCacheEntry(address).Tokens > 0) {
peek(requestNetwork_in, RequestMsg) {
- enqueue(responseNetwork_out, ResponseMsg, latency="L1_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency = l1_response_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:ACK;
out_msg.Sender := machineID;
@@ -1259,13 +1361,13 @@ machine(L1Cache, "Token protocol") {
action(ii_allocateL1DCacheBlock, "\i", desc="Set L1 D-cache tag equal to tag of block B.") {
if (L1DcacheMemory.isTagPresent(address) == false) {
- L1DcacheMemory.allocate(address);
+ L1DcacheMemory.allocate(address, new Entry);
}
}
action(pp_allocateL1ICacheBlock, "\p", desc="Set L1 I-cache tag equal to tag of block B.") {
if (L1IcacheMemory.isTagPresent(address) == false) {
- L1IcacheMemory.allocate(address);
+ L1IcacheMemory.allocate(address, new Entry);
}
}
@@ -1281,11 +1383,6 @@ machine(L1Cache, "Token protocol") {
}
}
-
- action(z_stall, "z", desc="Stall") {
-
- }
-
action(zz_recycleMandatoryQueue, "\z", desc="Send the head of the mandatory queue to the back of the queue.") {
mandatoryQueue_in.recycle();
}
diff --git a/src/mem/protocol/MOESI_CMP_token-L2cache.sm b/src/mem/protocol/MOESI_CMP_token-L2cache.sm
index 0a58ed5cf..9a5c400f2 100644
--- a/src/mem/protocol/MOESI_CMP_token-L2cache.sm
+++ b/src/mem/protocol/MOESI_CMP_token-L2cache.sm
@@ -32,20 +32,33 @@
*
*/
-machine(L2Cache, "Token protocol") {
+machine(L2Cache, "Token protocol")
+ : int l2_request_latency,
+ int l2_response_latency,
+ int N_tokens,
+ bool filtering_enabled
+{
// L2 BANK QUEUES
// From local bank of L2 cache TO the network
- MessageBuffer L1RequestFromL2Cache, network="To", virtual_network="0", ordered="false"; // this L2 bank -> a local L1
- MessageBuffer GlobalRequestFromL2Cache, network="To", virtual_network="1", ordered="false"; // this L2 bank -> mod-directory
- MessageBuffer responseFromL2Cache, network="To", virtual_network="2", ordered="false"; // this L2 bank -> a local L1 || mod-directory
+
+ // this L2 bank -> a local L1 || mod-directory
+ MessageBuffer responseFromL2Cache, network="To", virtual_network="1", ordered="false";
+ // this L2 bank -> mod-directory
+ MessageBuffer GlobalRequestFromL2Cache, network="To", virtual_network="3", ordered="false";
+ // this L2 bank -> a local L1
+ MessageBuffer L1RequestFromL2Cache, network="To", virtual_network="4", ordered="false";
// FROM the network to this local bank of L2 cache
- MessageBuffer L1RequestToL2Cache, network="From", virtual_network="0", ordered="false"; // a local L1 -> this L2 bank
- MessageBuffer GlobalRequestToL2Cache, network="From", virtual_network="1", ordered="false"; // mod-directory -> this L2 bank
- MessageBuffer responseToL2Cache, network="From", virtual_network="2", ordered="false"; // a local L1 || mod-directory -> this L2 bank
- MessageBuffer persistentToL2Cache, network="From", virtual_network="3", ordered="true";
+
+ // a local L1 || mod-directory -> this L2 bank
+ MessageBuffer responseToL2Cache, network="From", virtual_network="1", ordered="false";
+ MessageBuffer persistentToL2Cache, network="From", virtual_network="2", ordered="true";
+ // mod-directory -> this L2 bank
+ MessageBuffer GlobalRequestToL2Cache, network="From", virtual_network="3", ordered="false";
+ // a local L1 -> this L2 bank
+ MessageBuffer L1RequestToL2Cache, network="From", virtual_network="4", ordered="false";
// STATES
enumeration(State, desc="L2 Cache states", default="L2Cache_State_I") {
@@ -107,8 +120,6 @@ machine(L2Cache, "Token protocol") {
DataBlock DataBlk, desc="data for the block";
}
-
-
structure(DirEntry, desc="...") {
Set Sharers, desc="Set of the internal processors that want the block in shared state";
bool exclusive, default="false", desc="if local exclusive is likely";
@@ -117,7 +128,7 @@ machine(L2Cache, "Token protocol") {
external_type(CacheMemory) {
bool cacheAvail(Address);
Address cacheProbe(Address);
- void allocate(Address);
+ void allocate(Address, Entry);
void deallocate(Address);
Entry lookup(Address);
void changePermission(Address, AccessPermission);
@@ -132,19 +143,28 @@ machine(L2Cache, "Token protocol") {
bool isTagPresent(Address);
}
+ external_type(PersistentTable) {
+ void persistentRequestLock(Address, MachineID, AccessType);
+ void persistentRequestUnlock(Address, MachineID);
+ MachineID findSmallest(Address);
+ AccessType typeOfSmallest(Address);
+ void markEntries(Address);
+ bool isLocked(Address);
+ int countStarvingForAddress(Address);
+ int countReadStarvingForAddress(Address);
+ }
- CacheMemory L2cacheMemory, template_hack="<L2Cache_Entry>", constructor_hack='L2_CACHE_NUM_SETS_BITS,L2_CACHE_ASSOC,MachineType_L2Cache,int_to_string(i)+"_L2"';
+ CacheMemory L2cacheMemory, factory='RubySystem::getCache(m_cfg["cache"])';
- PersistentTable persistentTable, constructor_hack="i";
+ PersistentTable persistentTable;
PerfectCacheMemory localDirectory, template_hack="<L2Cache_DirEntry>";
-
- bool getFilteringEnabled();
-
Entry getL2CacheEntry(Address addr), return_by_ref="yes" {
if (L2cacheMemory.isTagPresent(addr)) {
return L2cacheMemory[addr];
}
+ assert(false);
+ return L2cacheMemory[addr];
}
int getTokens(Address addr) {
@@ -465,15 +485,21 @@ machine(L2Cache, "Token protocol") {
// if this is a retry or no local sharers, broadcast normally
// if (in_msg.RetryNum > 0 || (in_msg.Type == CoherenceRequestType:GETX && exclusiveExists(in_msg.Address) == false) || (in_msg.Type == CoherenceRequestType:GETS && sharersExist(in_msg.Address) == false)) {
- enqueue(globalRequestNetwork_out, RequestMsg, latency="L2_REQUEST_LATENCY") {
+ enqueue(globalRequestNetwork_out, RequestMsg, latency=l2_request_latency) {
out_msg.Address := in_msg.Address;
out_msg.Type := in_msg.Type;
out_msg.Requestor := in_msg.Requestor;
out_msg.RequestorMachine := in_msg.RequestorMachine;
- //out_msg.Destination.broadcast(MachineType:L2Cache);
out_msg.RetryNum := in_msg.RetryNum;
- out_msg.Destination.addNetDest(getAllPertinentL2Banks(address));
- out_msg.Destination.remove(map_L1CacheMachId_to_L2Cache(address, in_msg.Requestor));
+
+ //
+ // If a statically shared L2 cache, then no other L2 caches can
+ // store the block
+ //
+ //out_msg.Destination.broadcast(MachineType:L2Cache);
+ //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address));
+ //out_msg.Destination.remove(map_L1CacheMachId_to_L2Cache(address, in_msg.Requestor));
+
out_msg.Destination.add(map_Address_to_Directory(address));
out_msg.MessageSize := MessageSizeType:Request_Control;
out_msg.AccessMode := in_msg.AccessMode;
@@ -489,7 +515,7 @@ machine(L2Cache, "Token protocol") {
action(bb_bounceResponse, "\b", desc="Bounce tokens and data to memory") {
peek(responseNetwork_in, ResponseMsg) {
// FIXME, should use a 3rd vnet
- enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency="1") {
out_msg.Address := address;
out_msg.Type := in_msg.Type;
out_msg.Sender := machineID;
@@ -505,7 +531,7 @@ machine(L2Cache, "Token protocol") {
action(c_cleanReplacement, "c", desc="Issue clean writeback") {
if (getL2CacheEntry(address).Tokens > 0) {
- enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:ACK;
out_msg.Sender := machineID;
@@ -519,7 +545,7 @@ machine(L2Cache, "Token protocol") {
}
action(cc_dirtyReplacement, "\c", desc="Issue dirty writeback") {
- enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) {
out_msg.Address := address;
out_msg.Sender := machineID;
out_msg.SenderMachine := MachineType:L2Cache;
@@ -541,22 +567,22 @@ machine(L2Cache, "Token protocol") {
action(d_sendDataWithTokens, "d", desc="Send data and a token from cache to requestor") {
peek(requestNetwork_in, RequestMsg) {
- if (getL2CacheEntry(address).Tokens > N_tokens()) {
- enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+ if (getL2CacheEntry(address).Tokens > N_tokens) {
+ enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:DATA_SHARED;
out_msg.Sender := machineID;
out_msg.SenderMachine := MachineType:L2Cache;
out_msg.Destination.add(in_msg.Requestor);
- out_msg.Tokens := N_tokens();
+ out_msg.Tokens := N_tokens;
out_msg.DataBlk := getL2CacheEntry(address).DataBlk;
out_msg.Dirty := false;
out_msg.MessageSize := MessageSizeType:Response_Data;
}
- getL2CacheEntry(address).Tokens := getL2CacheEntry(address).Tokens - N_tokens();
+ getL2CacheEntry(address).Tokens := getL2CacheEntry(address).Tokens - N_tokens;
}
else {
- enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:DATA_SHARED;
out_msg.Sender := machineID;
@@ -574,7 +600,7 @@ machine(L2Cache, "Token protocol") {
action(dd_sendDataWithAllTokens, "\d", desc="Send data and all tokens from cache to requestor") {
peek(requestNetwork_in, RequestMsg) {
- enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:DATA_OWNER;
out_msg.Sender := machineID;
@@ -592,7 +618,7 @@ machine(L2Cache, "Token protocol") {
action(e_sendAckWithCollectedTokens, "e", desc="Send ack with the tokens we've collected thus far.") {
if (getL2CacheEntry(address).Tokens > 0) {
- enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:ACK;
out_msg.Sender := machineID;
@@ -607,7 +633,7 @@ machine(L2Cache, "Token protocol") {
}
action(ee_sendDataWithAllTokens, "\e", desc="Send data and all tokens from cache to starver") {
- enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:DATA_OWNER;
out_msg.Sender := machineID;
@@ -626,7 +652,7 @@ machine(L2Cache, "Token protocol") {
//assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself
assert(getL2CacheEntry(address).Tokens > 0);
if (getL2CacheEntry(address).Tokens > 1) {
- enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:ACK;
out_msg.Sender := machineID;
@@ -644,7 +670,7 @@ machine(L2Cache, "Token protocol") {
//assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself
assert(getL2CacheEntry(address).Tokens > 0);
if (getL2CacheEntry(address).Tokens > 1) {
- enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:DATA_OWNER;
out_msg.Sender := machineID;
@@ -666,7 +692,7 @@ machine(L2Cache, "Token protocol") {
// assert(persistentTable.isLocked(address));
peek(responseNetwork_in, ResponseMsg) {
// FIXME, should use a 3rd vnet in some cases
- enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency="1") {
out_msg.Address := address;
out_msg.Type := in_msg.Type;
out_msg.Sender := machineID;
@@ -684,7 +710,7 @@ machine(L2Cache, "Token protocol") {
//assert(persistentTable.isLocked(address));
peek(responseNetwork_in, ResponseMsg) {
// FIXME, should use a 3rd vnet in some cases
- enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency="1") {
out_msg.Address := address;
if (in_msg.Type == CoherenceResponseType:WB_SHARED_DATA) {
out_msg.Type := CoherenceResponseType:DATA_SHARED;
@@ -706,7 +732,7 @@ machine(L2Cache, "Token protocol") {
// assert(persistentTable.isLocked(address));
peek(responseNetwork_in, ResponseMsg) {
// FIXME, should use a 3rd vnet in some cases
- enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency="1") {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:DATA_OWNER;
out_msg.Sender := machineID;
@@ -729,24 +755,31 @@ machine(L2Cache, "Token protocol") {
action(j_forwardTransientRequestToLocalSharers, "j", desc="Forward external transient request to local sharers") {
peek(requestNetwork_in, RequestMsg) {
- if (getFilteringEnabled() == true && in_msg.RetryNum == 0 && sharersExist(in_msg.Address) == false) {
- profile_filter_action(1);
+ if (filtering_enabled == true && in_msg.RetryNum == 0 && sharersExist(in_msg.Address) == false) {
+ //profile_filter_action(1);
DEBUG_EXPR("filtered message");
DEBUG_EXPR(in_msg.RetryNum);
}
else {
- enqueue( localRequestNetwork_out, RequestMsg, latency="L2_RESPONSE_LATENCY" ) {
+ enqueue(localRequestNetwork_out, RequestMsg, latency=l2_response_latency ) {
out_msg.Address := in_msg.Address;
out_msg.Requestor := in_msg.Requestor;
out_msg.RequestorMachine := in_msg.RequestorMachine;
- out_msg.Destination := getLocalL1IDs(machineID);
+
+ //
+ // Currently assuming only one chip so all L1s are local
+ //
+ //out_msg.Destination := getLocalL1IDs(machineID);
+ out_msg.Destination.broadcast(MachineType:L1Cache);
+ out_msg.Destination.remove(in_msg.Requestor);
+
out_msg.Type := in_msg.Type;
out_msg.isLocal := false;
out_msg.MessageSize := MessageSizeType:Request_Control;
out_msg.AccessMode := in_msg.AccessMode;
out_msg.Prefetch := in_msg.Prefetch;
}
- profile_filter_action(0);
+ //profile_filter_action(0);
}
}
}
@@ -756,7 +789,7 @@ machine(L2Cache, "Token protocol") {
peek(L1requestNetwork_in, RequestMsg) {
assert(getL2CacheEntry(address).Tokens > 0);
//enqueue(responseIntraChipL2Network_out, ResponseMsg, latency="L2_to_L1_RESPONSE_LATENCY") {
- enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:DATA_SHARED;
out_msg.Sender := machineID;
@@ -774,7 +807,7 @@ machine(L2Cache, "Token protocol") {
action(k_dataOwnerFromL2CacheToL1Requestor, "\k", desc="Send data and a token from cache to L1 requestor") {
peek(L1requestNetwork_in, RequestMsg) {
assert(getL2CacheEntry(address).Tokens > 0);
- enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:DATA_OWNER;
out_msg.Sender := machineID;
@@ -793,7 +826,7 @@ machine(L2Cache, "Token protocol") {
peek(L1requestNetwork_in, RequestMsg) {
// assert(getL2CacheEntry(address).Tokens == max_tokens());
//enqueue(responseIntraChipL2Network_out, ResponseMsg, latency="L2_to_L1_RESPONSE_LATENCY") {
- enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:DATA_OWNER;
out_msg.Sender := machineID;
@@ -840,12 +873,13 @@ machine(L2Cache, "Token protocol") {
}
action(r_markNewSharer, "r", desc="Mark the new local sharer from local request message") {
-
peek(L1requestNetwork_in, RequestMsg) {
- if (in_msg.Type == CoherenceRequestType:GETX) {
- setNewWriter(in_msg.Address, machineIDToNodeID(in_msg.Requestor));
- } else if (in_msg.Type == CoherenceRequestType:GETS) {
- addNewSharer(in_msg.Address, machineIDToNodeID(in_msg.Requestor));
+ if (machineIDToMachineType(in_msg.Requestor) == MachineType:L1Cache) {
+ if (in_msg.Type == CoherenceRequestType:GETX) {
+ setNewWriter(in_msg.Address, machineIDToNodeID(in_msg.Requestor));
+ } else if (in_msg.Type == CoherenceRequestType:GETS) {
+ addNewSharer(in_msg.Address, machineIDToNodeID(in_msg.Requestor));
+ }
}
}
}
@@ -854,16 +888,19 @@ machine(L2Cache, "Token protocol") {
clearExclusiveBitIfExists(address);
}
- action( r_setMRU, "\rr", desc="manually set the MRU bit for cache line" ) {
- if(isCacheTagPresent(address)) {
- L2cacheMemory.setMRU(address);
+ action(r_setMRU, "\rr", desc="manually set the MRU bit for cache line" ) {
+ peek(L1requestNetwork_in, RequestMsg) {
+ if ((machineIDToMachineType(in_msg.Requestor) == MachineType:L1Cache) &&
+ (isCacheTagPresent(address))) {
+ L2cacheMemory.setMRU(address);
+ }
}
}
action(t_sendAckWithCollectedTokens, "t", desc="Send ack with the tokens we've collected thus far.") {
if (getL2CacheEntry(address).Tokens > 0) {
peek(requestNetwork_in, RequestMsg) {
- enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:ACK;
out_msg.Sender := machineID;
@@ -881,7 +918,7 @@ machine(L2Cache, "Token protocol") {
action(tt_sendLocalAckWithCollectedTokens, "tt", desc="Send ack with the tokens we've collected thus far.") {
if (getL2CacheEntry(address).Tokens > 0) {
peek(L1requestNetwork_in, RequestMsg) {
- enqueue(responseNetwork_out, ResponseMsg, latency="L2_RESPONSE_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:ACK;
out_msg.Sender := machineID;
@@ -906,19 +943,19 @@ machine(L2Cache, "Token protocol") {
}
action(vv_allocateL2CacheBlock, "\v", desc="Set L2 cache tag equal to tag of block B.") {
- L2cacheMemory.allocate(address);
+ L2cacheMemory.allocate(address, new Entry);
}
action(rr_deallocateL2CacheBlock, "\r", desc="Deallocate L2 cache block. Sets the cache to not present, allowing a replacement in parallel with a fetch.") {
L2cacheMemory.deallocate(address);
}
- action(uu_profileMiss, "\u", desc="Profile the demand miss") {
- peek(L1requestNetwork_in, RequestMsg) {
+ //action(uu_profileMiss, "\u", desc="Profile the demand miss") {
+ // peek(L1requestNetwork_in, RequestMsg) {
// AccessModeType not implemented
//profile_L2Cache_miss(convertToGenericType(in_msg.Type), in_msg.AccessMode, MessageSizeTypeToInt(in_msg.MessageSize), in_msg.Prefetch, machineIDToNodeID(in_msg.Requestor));
- }
- }
+ // }
+ //}
action(w_assertIncomingDataAndCacheDataMatch, "w", desc="Assert that the incoming data and the data in the cache match") {
@@ -927,11 +964,6 @@ machine(L2Cache, "Token protocol") {
}
}
- action(z_stall, "z", desc="Stall") {
- }
-
-
-
//*****************************************************
// TRANSITIONS
@@ -961,7 +993,7 @@ machine(L2Cache, "Token protocol") {
transition(NP, {L1_GETS, L1_GETX}) {
a_broadcastLocalRequest;
r_markNewSharer;
- uu_profileMiss;
+ //uu_profileMiss;
o_popL1RequestQueue;
}
@@ -1012,7 +1044,7 @@ machine(L2Cache, "Token protocol") {
a_broadcastLocalRequest;
tt_sendLocalAckWithCollectedTokens; // send any tokens we have collected
r_markNewSharer;
- uu_profileMiss;
+ //uu_profileMiss;
o_popL1RequestQueue;
}
@@ -1020,7 +1052,7 @@ machine(L2Cache, "Token protocol") {
a_broadcastLocalRequest;
tt_sendLocalAckWithCollectedTokens; // send any tokens we have collected
r_markNewSharer;
- uu_profileMiss;
+ //uu_profileMiss;
o_popL1RequestQueue;
}
@@ -1181,7 +1213,7 @@ machine(L2Cache, "Token protocol") {
tt_sendLocalAckWithCollectedTokens;
r_markNewSharer;
r_setMRU;
- uu_profileMiss;
+ //uu_profileMiss;
o_popL1RequestQueue;
}
@@ -1294,7 +1326,7 @@ machine(L2Cache, "Token protocol") {
k_dataAndAllTokensFromL2CacheToL1Requestor;
r_markNewSharer;
r_setMRU;
- uu_profileMiss;
+ //uu_profileMiss;
o_popL1RequestQueue;
}
@@ -1382,7 +1414,7 @@ machine(L2Cache, "Token protocol") {
transition(I_L, {L1_GETX, L1_GETS}) {
a_broadcastLocalRequest;
r_markNewSharer;
- uu_profileMiss;
+ //uu_profileMiss;
o_popL1RequestQueue;
}
@@ -1391,7 +1423,7 @@ machine(L2Cache, "Token protocol") {
tt_sendLocalAckWithCollectedTokens;
r_markNewSharer;
r_setMRU;
- uu_profileMiss;
+ //uu_profileMiss;
o_popL1RequestQueue;
}
diff --git a/src/mem/protocol/MOESI_CMP_token-dir.sm b/src/mem/protocol/MOESI_CMP_token-dir.sm
index 1592fd123..7925a8fe0 100644
--- a/src/mem/protocol/MOESI_CMP_token-dir.sm
+++ b/src/mem/protocol/MOESI_CMP_token-dir.sm
@@ -32,14 +32,23 @@
*/
-machine(Directory, "Token protocol") {
-
- MessageBuffer requestFromDir, network="To", virtual_network="1", ordered="false";
- MessageBuffer responseFromDir, network="To", virtual_network="2", ordered="false";
-
- MessageBuffer persistentToDir, network="From", virtual_network="3", ordered="true";
- MessageBuffer requestToDir, network="From", virtual_network="1", ordered="false";
- MessageBuffer responseToDir, network="From", virtual_network="2", ordered="false";
+machine(Directory, "Token protocol")
+ : int directory_latency,
+ int l2_select_low_bit,
+ int l2_select_num_bits,
+ bool distributed_persistent,
+ int fixed_timeout_latency
+{
+
+ MessageBuffer dmaResponseFromDir, network="To", virtual_network="0", ordered="true";
+ MessageBuffer responseFromDir, network="To", virtual_network="1", ordered="false";
+ MessageBuffer persistentFromDir, network="To", virtual_network="2", ordered="true";
+ MessageBuffer requestFromDir, network="To", virtual_network="4", ordered="false";
+
+ MessageBuffer responseToDir, network="From", virtual_network="1", ordered="false";
+ MessageBuffer persistentToDir, network="From", virtual_network="2", ordered="true";
+ MessageBuffer requestToDir, network="From", virtual_network="3", ordered="false";
+ MessageBuffer dmaRequestToDir, network="From", virtual_network="5", ordered="true";
// STATES
enumeration(State, desc="Directory states", default="Directory_State_O") {
@@ -47,6 +56,24 @@ machine(Directory, "Token protocol") {
O, desc="Owner";
NO, desc="Not Owner";
L, desc="Locked";
+
+ // Memory wait states - can block all messages including persistent requests
+ O_W, desc="transitioning to Owner, waiting for memory write";
+ L_W, desc="transitioning to Locked, waiting for memory read";
+ DR_L_W, desc="transitioning to Locked underneath a DMA read, waiting for memory data";
+ NO_W, desc="transitioning to Not Owner, waiting for memory read";
+ O_DW_W, desc="transitioning to Owner, waiting for memory before DMA ack";
+ O_DR_W, desc="transitioning to Owner, waiting for memory before DMA data";
+
+ // DMA request transient states - must respond to persistent requests
+ O_DW, desc="issued GETX for DMA write, waiting for all tokens";
+ NO_DW, desc="issued GETX for DMA write, waiting for all tokens";
+ NO_DR, desc="issued GETS for DMA read, waiting for data";
+
+ // DMA request in progress - competing with a CPU persistent request
+ DW_L, desc="issued GETX for DMA write, CPU persistent request must complete first";
+ DR_L, desc="issued GETS for DMA read, CPU persistent request must complete first";
+
}
// Events
@@ -55,9 +82,23 @@ machine(Directory, "Token protocol") {
GETS, desc="A GETS arrives";
Lockdown, desc="A lockdown request arrives";
Unlockdown, desc="An un-lockdown request arrives";
+ Own_Lock_or_Unlock, desc="own lock or unlock";
Data_Owner, desc="Data arrive";
+ Data_All_Tokens, desc="Data and all tokens";
Ack_Owner, desc="Owner token arrived without data because it was clean";
+ Ack_Owner_All_Tokens, desc="All tokens including owner arrived without data because it was clean";
Tokens, desc="Tokens arrive";
+ Ack_All_Tokens, desc="All_Tokens arrive";
+ Request_Timeout, desc="A DMA request has timed out";
+
+ // Memory Controller
+ Memory_Data, desc="Fetched data from memory arrives";
+ Memory_Ack, desc="Writeback Ack from memory arrives";
+
+ // DMA requests
+ DMA_READ, desc="A DMA Read memory request";
+ DMA_WRITE, desc="A DMA Write memory request";
+ DMA_WRITE_All_Tokens, desc="A DMA Write memory request, directory has all tokens";
}
// TYPES
@@ -73,7 +114,7 @@ machine(Directory, "Token protocol") {
// is 'soft state' that does not need to be correct (as long as
// you're eventually willing to resort to broadcast.)
- Set Owner, desc="Probable Owner of the line. More accurately, the set of processors who need to see a GetS or GetO. We use a Set for convenience, but only one bit is set at a time.";
+ Set Owner, desc="Probable Owner of the line. More accurately, the set of processors who need to see a GetS or GetO. We use a Set for convenience, but only one bit is set at a time.";
Set Sharers, desc="Probable sharers of the line. More accurately, the set of processors who need to see a GetX";
}
@@ -82,23 +123,70 @@ machine(Directory, "Token protocol") {
bool isPresent(Address);
}
+ external_type(MemoryControl, inport="yes", outport="yes") {
+
+ }
+
+ external_type(PersistentTable) {
+ void persistentRequestLock(Address, MachineID, AccessType);
+ void persistentRequestUnlock(Address, MachineID);
+ bool okToIssueStarving(Address, MachineID);
+ MachineID findSmallest(Address);
+ AccessType typeOfSmallest(Address);
+ void markEntries(Address);
+ bool isLocked(Address);
+ int countStarvingForAddress(Address);
+ int countReadStarvingForAddress(Address);
+ }
+
+ // TBE entries for DMA requests
+ structure(TBE, desc="TBE entries for outstanding DMA requests") {
+ Address PhysicalAddress, desc="physical address";
+ State TBEState, desc="Transient State";
+ DataBlock DmaDataBlk, desc="DMA Data to be written. Partial blocks need to merged with system memory";
+ DataBlock DataBlk, desc="The current view of system memory";
+ int Len, desc="...";
+ MachineID DmaRequestor, desc="DMA requestor";
+ bool WentPersistent, desc="Did the DMA request require a persistent request";
+ }
+
+ external_type(TBETable) {
+ TBE lookup(Address);
+ void allocate(Address);
+ void deallocate(Address);
+ bool isPresent(Address);
+ }
// ** OBJECTS **
- DirectoryMemory directory, constructor_hack="i";
+ DirectoryMemory directory, factory='RubySystem::getDirectory(m_cfg["directory_name"])';
+
+ MemoryControl memBuffer, factory='RubySystem::getMemoryControl(m_cfg["memory_controller_name"])';
- PersistentTable persistentTable, constructor_hack="i";
+ PersistentTable persistentTable;
+ TimerTable reissueTimerTable;
+
+ TBETable TBEs, template_hack="<Directory_TBE>";
+
+ bool starving, default="false";
State getState(Address addr) {
- return directory[addr].DirectoryState;
+ if (TBEs.isPresent(addr)) {
+ return TBEs[addr].TBEState;
+ } else {
+ return directory[addr].DirectoryState;
+ }
}
void setState(Address addr, State state) {
+ if (TBEs.isPresent(addr)) {
+ TBEs[addr].TBEState := state;
+ }
directory[addr].DirectoryState := state;
if (state == State:L) {
assert(directory[addr].Tokens == 0);
- }
+ }
// We have one or zero owners
assert((directory[addr].Owner.count() == 0) || (directory[addr].Owner.count() == 1));
@@ -112,19 +200,90 @@ machine(Directory, "Token protocol") {
// assert(directory[addr].Tokens >= (max_tokens() / 2)); // Only mostly true; this might not always hold
}
}
+
+ bool okToIssueStarving(Address addr, MachineID machinID) {
+ return persistentTable.okToIssueStarving(addr, machineID);
+ }
+
+ void markPersistentEntries(Address addr) {
+ persistentTable.markEntries(addr);
+ }
// ** OUT_PORTS **
out_port(responseNetwork_out, ResponseMsg, responseFromDir);
+ out_port(persistentNetwork_out, PersistentMsg, persistentFromDir);
out_port(requestNetwork_out, RequestMsg, requestFromDir);
+ out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir);
+
+ //
+ // Memory buffer for memory controller to DIMM communication
+ //
+ out_port(memQueue_out, MemoryMsg, memBuffer);
// ** IN_PORTS **
+
+ // off-chip memory request/response is done
+ in_port(memQueue_in, MemoryMsg, memBuffer) {
+ if (memQueue_in.isReady()) {
+ peek(memQueue_in, MemoryMsg) {
+ if (in_msg.Type == MemoryRequestType:MEMORY_READ) {
+ trigger(Event:Memory_Data, in_msg.Address);
+ } else if (in_msg.Type == MemoryRequestType:MEMORY_WB) {
+ trigger(Event:Memory_Ack, in_msg.Address);
+ } else {
+ DEBUG_EXPR(in_msg.Type);
+ error("Invalid message");
+ }
+ }
+ }
+ }
+
+ // Reissue Timer
+ in_port(reissueTimerTable_in, Address, reissueTimerTable) {
+ if (reissueTimerTable_in.isReady()) {
+ trigger(Event:Request_Timeout, reissueTimerTable.readyAddress());
+ }
+ }
+
+ in_port(responseNetwork_in, ResponseMsg, responseToDir) {
+ if (responseNetwork_in.isReady()) {
+ peek(responseNetwork_in, ResponseMsg) {
+ assert(in_msg.Destination.isElement(machineID));
+ if (directory[in_msg.Address].Tokens + in_msg.Tokens == max_tokens()) {
+ if ((in_msg.Type == CoherenceResponseType:DATA_OWNER) ||
+ (in_msg.Type == CoherenceResponseType:DATA_SHARED)) {
+ trigger(Event:Data_All_Tokens, in_msg.Address);
+ } else if (in_msg.Type == CoherenceResponseType:ACK_OWNER) {
+ trigger(Event:Ack_Owner_All_Tokens, in_msg.Address);
+ } else if (in_msg.Type == CoherenceResponseType:ACK) {
+ trigger(Event:Ack_All_Tokens, in_msg.Address);
+ } else {
+ DEBUG_EXPR(in_msg.Type);
+ error("Invalid message");
+ }
+ } else {
+ if (in_msg.Type == CoherenceResponseType:DATA_OWNER) {
+ trigger(Event:Data_Owner, in_msg.Address);
+ } else if ((in_msg.Type == CoherenceResponseType:ACK) ||
+ (in_msg.Type == CoherenceResponseType:DATA_SHARED)) {
+ trigger(Event:Tokens, in_msg.Address);
+ } else if (in_msg.Type == CoherenceResponseType:ACK_OWNER) {
+ trigger(Event:Ack_Owner, in_msg.Address);
+ } else {
+ DEBUG_EXPR(in_msg.Type);
+ error("Invalid message");
+ }
+ }
+ }
+ }
+ }
in_port(persistentNetwork_in, PersistentMsg, persistentToDir) {
if (persistentNetwork_in.isReady()) {
peek(persistentNetwork_in, PersistentMsg) {
assert(in_msg.Destination.isElement(machineID));
- if (distributedPersistentEnabled()) {
+ if (distributed_persistent) {
// Apply the lockdown or unlockdown message to the table
if (in_msg.Type == PersistentRequestType:GETX_PERSISTENT) {
persistentTable.persistentRequestLock(in_msg.Address, in_msg.Requestor, AccessType:Write);
@@ -173,19 +332,18 @@ machine(Directory, "Token protocol") {
}
}
- in_port(responseNetwork_in, ResponseMsg, responseToDir) {
- if (responseNetwork_in.isReady()) {
- peek(responseNetwork_in, ResponseMsg) {
- assert(in_msg.Destination.isElement(machineID));
- if (in_msg.Type == CoherenceResponseType:DATA_OWNER) {
- trigger(Event:Data_Owner, in_msg.Address);
- } else if ((in_msg.Type == CoherenceResponseType:ACK) ||
- (in_msg.Type == CoherenceResponseType:DATA_SHARED)) {
- trigger(Event:Tokens, in_msg.Address);
- } else if (in_msg.Type == CoherenceResponseType:ACK_OWNER) {
- trigger(Event:Ack_Owner, in_msg.Address);
+ in_port(dmaRequestQueue_in, DMARequestMsg, dmaRequestToDir) {
+ if (dmaRequestQueue_in.isReady()) {
+ peek(dmaRequestQueue_in, DMARequestMsg) {
+ if (in_msg.Type == DMARequestType:READ) {
+ trigger(Event:DMA_READ, in_msg.LineAddress);
+ } else if (in_msg.Type == DMARequestType:WRITE) {
+ if (directory[in_msg.LineAddress].Tokens == max_tokens()) {
+ trigger(Event:DMA_WRITE_All_Tokens, in_msg.LineAddress);
+ } else {
+ trigger(Event:DMA_WRITE, in_msg.LineAddress);
+ }
} else {
- DEBUG_EXPR(in_msg.Type);
error("Invalid message");
}
}
@@ -199,7 +357,7 @@ machine(Directory, "Token protocol") {
if (directory[address].Tokens > 0) {
peek(requestNetwork_in, RequestMsg) {
// enqueue(responseNetwork_out, ResponseMsg, latency="DIRECTORY_CACHE_LATENCY") {// FIXME?
- enqueue(responseNetwork_out, ResponseMsg, latency="DIRECTORY_LATENCY") {// FIXME?
+ enqueue(responseNetwork_out, ResponseMsg, latency=directory_latency) {// FIXME?
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:ACK;
out_msg.Sender := machineID;
@@ -213,11 +371,151 @@ machine(Directory, "Token protocol") {
}
}
+ action(px_tryIssuingPersistentGETXRequest, "px", desc="...") {
+ if (okToIssueStarving(address, machineID) && (starving == false)) {
+ enqueue(persistentNetwork_out, PersistentMsg, latency = "1") {
+ out_msg.Address := address;
+ out_msg.Type := PersistentRequestType:GETX_PERSISTENT;
+ out_msg.Requestor := machineID;
+ out_msg.RequestorMachine := MachineType:Directory;
+ out_msg.Destination.broadcast(MachineType:L1Cache);
+
+ //
+ // Currently the configuration system limits the system to only one
+ // chip. Therefore, if we assume one shared L2 cache, then only one
+ // pertinent L2 cache exist.
+ //
+ //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address));
+
+ out_msg.Destination.add(mapAddressToRange(address,
+ MachineType:L2Cache,
+ l2_select_low_bit,
+ l2_select_num_bits));
+
+ out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.MessageSize := MessageSizeType:Persistent_Control;
+ out_msg.Prefetch := PrefetchBit:No;
+ out_msg.AccessMode := AccessModeType:SupervisorMode;
+ }
+ markPersistentEntries(address);
+ starving := true;
+
+ TBEs[address].WentPersistent := true;
+
+ // Do not schedule a wakeup, a persistent requests will always complete
+ } else {
+
+ // We'd like to issue a persistent request, but are not allowed
+ // to issue a P.R. right now. This, we do not increment the
+ // IssueCount.
+
+ // Set a wakeup timer
+ reissueTimerTable.set(address, 10);
+ }
+ }
+
+ action(bw_broadcastWrite, "bw", desc="Broadcast GETX if we need tokens") {
+ peek(dmaRequestQueue_in, DMARequestMsg) {
+ //
+ // Assser that we only send message if we don't already have all the tokens
+ //
+ assert(directory[address].Tokens != max_tokens());
+ enqueue(requestNetwork_out, RequestMsg, latency = "1") {
+ out_msg.Address := address;
+ out_msg.Type := CoherenceRequestType:GETX;
+ out_msg.Requestor := machineID;
+ out_msg.RequestorMachine := MachineType:Directory;
+
+ //
+ // Since only one chip, assuming all L1 caches are local
+ //
+ out_msg.Destination.broadcast(MachineType:L1Cache);
+ out_msg.Destination.add(mapAddressToRange(address,
+ MachineType:L2Cache,
+ l2_select_low_bit,
+ l2_select_num_bits));
+
+ out_msg.RetryNum := 0;
+ out_msg.MessageSize := MessageSizeType:Request_Control;
+ out_msg.Prefetch := PrefetchBit:No;
+ out_msg.AccessMode := AccessModeType:SupervisorMode;
+ }
+ }
+ }
+
+ action(ps_tryIssuingPersistentGETSRequest, "ps", desc="...") {
+ if (okToIssueStarving(address, machineID) && (starving == false)) {
+ enqueue(persistentNetwork_out, PersistentMsg, latency = "1") {
+ out_msg.Address := address;
+ out_msg.Type := PersistentRequestType:GETS_PERSISTENT;
+ out_msg.Requestor := machineID;
+ out_msg.RequestorMachine := MachineType:Directory;
+ out_msg.Destination.broadcast(MachineType:L1Cache);
+
+ //
+ // Currently the configuration system limits the system to only one
+ // chip. Therefore, if we assume one shared L2 cache, then only one
+ // pertinent L2 cache exist.
+ //
+ //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address));
+
+ out_msg.Destination.add(mapAddressToRange(address,
+ MachineType:L2Cache,
+ l2_select_low_bit,
+ l2_select_num_bits));
+
+ out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.MessageSize := MessageSizeType:Persistent_Control;
+ out_msg.Prefetch := PrefetchBit:No;
+ out_msg.AccessMode := AccessModeType:SupervisorMode;
+ }
+ markPersistentEntries(address);
+ starving := true;
+
+ TBEs[address].WentPersistent := true;
+
+ // Do not schedule a wakeup, a persistent requests will always complete
+ } else {
+
+ // We'd like to issue a persistent request, but are not allowed
+ // to issue a P.R. right now. This, we do not increment the
+ // IssueCount.
+
+ // Set a wakeup timer
+ reissueTimerTable.set(address, 10);
+ }
+ }
+
+ action(br_broadcastRead, "br", desc="Broadcast GETS for data") {
+ peek(dmaRequestQueue_in, DMARequestMsg) {
+ enqueue(requestNetwork_out, RequestMsg, latency = "1") {
+ out_msg.Address := address;
+ out_msg.Type := CoherenceRequestType:GETS;
+ out_msg.Requestor := machineID;
+ out_msg.RequestorMachine := MachineType:Directory;
+
+ //
+ // Since only one chip, assuming all L1 caches are local
+ //
+ out_msg.Destination.broadcast(MachineType:L1Cache);
+ out_msg.Destination.add(mapAddressToRange(address,
+ MachineType:L2Cache,
+ l2_select_low_bit,
+ l2_select_num_bits));
+
+ out_msg.RetryNum := 0;
+ out_msg.MessageSize := MessageSizeType:Request_Control;
+ out_msg.Prefetch := PrefetchBit:No;
+ out_msg.AccessMode := AccessModeType:SupervisorMode;
+ }
+ }
+ }
+
action(aa_sendTokensToStarver, "\a", desc="Send tokens to starver") {
// Only send a message if we have tokens to send
if (directory[address].Tokens > 0) {
// enqueue(responseNetwork_out, ResponseMsg, latency="DIRECTORY_CACHE_LATENCY") {// FIXME?
- enqueue(responseNetwork_out, ResponseMsg, latency="DIRECTORY_LATENCY") {// FIXME?
+ enqueue(responseNetwork_out, ResponseMsg, latency=directory_latency) {// FIXME?
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:ACK;
out_msg.Sender := machineID;
@@ -230,14 +528,14 @@ machine(Directory, "Token protocol") {
}
}
- action(d_sendDataWithAllTokens, "d", desc="Send data and tokens to requestor") {
- peek(requestNetwork_in, RequestMsg) {
- enqueue(responseNetwork_out, ResponseMsg, latency="MEMORY_LATENCY") {
+ action(d_sendMemoryDataWithAllTokens, "d", desc="Send data and tokens to requestor") {
+ peek(memQueue_in, MemoryMsg) {
+ enqueue(responseNetwork_out, ResponseMsg, latency="1") {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:DATA_OWNER;
out_msg.Sender := machineID;
out_msg.SenderMachine := MachineType:Directory;
- out_msg.Destination.add(in_msg.Requestor);
+ out_msg.Destination.add(in_msg.OriginalRequestorMachId);
assert(directory[address].Tokens > 0);
out_msg.Tokens := directory[in_msg.Address].Tokens;
out_msg.DataBlk := directory[in_msg.Address].DataBlk;
@@ -249,21 +547,140 @@ machine(Directory, "Token protocol") {
}
action(dd_sendDataWithAllTokensToStarver, "\d", desc="Send data and tokens to starver") {
- enqueue(responseNetwork_out, ResponseMsg, latency="MEMORY_LATENCY") {
- out_msg.Address := address;
- out_msg.Type := CoherenceResponseType:DATA_OWNER;
- out_msg.Sender := machineID;
- out_msg.SenderMachine := MachineType:Directory;
- out_msg.Destination.add(persistentTable.findSmallest(address));
- assert(directory[address].Tokens > 0);
- out_msg.Tokens := directory[address].Tokens;
- out_msg.DataBlk := directory[address].DataBlk;
- out_msg.Dirty := false;
- out_msg.MessageSize := MessageSizeType:Response_Data;
+ peek(memQueue_in, MemoryMsg) {
+ enqueue(responseNetwork_out, ResponseMsg, latency="1") {
+ out_msg.Address := address;
+ out_msg.Type := CoherenceResponseType:DATA_OWNER;
+ out_msg.Sender := machineID;
+ out_msg.SenderMachine := MachineType:Directory;
+ out_msg.Destination.add(persistentTable.findSmallest(address));
+ assert(directory[address].Tokens > 0);
+ out_msg.Tokens := directory[address].Tokens;
+ out_msg.DataBlk := directory[address].DataBlk;
+ out_msg.Dirty := false;
+ out_msg.MessageSize := MessageSizeType:Response_Data;
+ }
}
directory[address].Tokens := 0;
}
+ action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
+ peek(requestNetwork_in, RequestMsg) {
+ enqueue(memQueue_out, MemoryMsg, latency="1") {
+ out_msg.Address := address;
+ out_msg.Type := MemoryRequestType:MEMORY_READ;
+ out_msg.Sender := machineID;
+ out_msg.OriginalRequestorMachId := in_msg.Requestor;
+ out_msg.MessageSize := in_msg.MessageSize;
+ out_msg.DataBlk := directory[address].DataBlk;
+ DEBUG_EXPR(out_msg);
+ }
+ }
+ }
+
+ action(fd_memoryDma, "fd", desc="Queue off-chip fetch request") {
+ peek(dmaRequestQueue_in, DMARequestMsg) {
+ enqueue(memQueue_out, MemoryMsg, latency="1") {
+ out_msg.Address := address;
+ out_msg.Type := MemoryRequestType:MEMORY_READ;
+ out_msg.Sender := machineID;
+ out_msg.OriginalRequestorMachId := in_msg.Requestor;
+ out_msg.MessageSize := in_msg.MessageSize;
+ out_msg.DataBlk := directory[address].DataBlk;
+ DEBUG_EXPR(out_msg);
+ }
+ }
+ }
+
+ action(lq_queueMemoryWbRequest, "lq", desc="Write data to memory") {
+ enqueue(memQueue_out, MemoryMsg, latency="1") {
+ out_msg.Address := address;
+ out_msg.Type := MemoryRequestType:MEMORY_WB;
+ DEBUG_EXPR(out_msg);
+ }
+ }
+
+ action(ld_queueMemoryDmaWriteFromTbe, "ld", desc="Write DMA data to memory") {
+ enqueue(memQueue_out, MemoryMsg, latency="1") {
+ out_msg.Address := address;
+ out_msg.Type := MemoryRequestType:MEMORY_WB;
+ // first, initialize the data blk to the current version of system memory
+ out_msg.DataBlk := TBEs[address].DataBlk;
+ // then add the dma write data
+ out_msg.DataBlk.copyPartial(TBEs[address].DmaDataBlk, addressOffset(TBEs[address].PhysicalAddress), TBEs[address].Len);
+ DEBUG_EXPR(out_msg);
+ }
+ }
+
+ action(lr_queueMemoryDmaReadWriteback, "lr", desc="Write DMA data from read to memory") {
+ enqueue(memQueue_out, MemoryMsg, latency="1") {
+ out_msg.Address := address;
+ out_msg.Type := MemoryRequestType:MEMORY_WB;
+ // first, initialize the data blk to the current version of system memory
+ out_msg.DataBlk := TBEs[address].DataBlk;
+ DEBUG_EXPR(out_msg);
+ }
+ }
+
+ action(vd_allocateDmaRequestInTBE, "vd", desc="Record Data in TBE") {
+ peek(dmaRequestQueue_in, DMARequestMsg) {
+ TBEs.allocate(address);
+ TBEs[address].DmaDataBlk := in_msg.DataBlk;
+ TBEs[address].PhysicalAddress := in_msg.PhysicalAddress;
+ TBEs[address].Len := in_msg.Len;
+ TBEs[address].DmaRequestor := in_msg.Requestor;
+ TBEs[address].WentPersistent := false;
+ }
+ }
+
+ action(s_deallocateTBE, "s", desc="Deallocate TBE") {
+
+ if (TBEs[address].WentPersistent) {
+ assert(starving == true);
+
+ enqueue(persistentNetwork_out, PersistentMsg, latency = "1") {
+ out_msg.Address := address;
+ out_msg.Type := PersistentRequestType:DEACTIVATE_PERSISTENT;
+ out_msg.Requestor := machineID;
+ out_msg.RequestorMachine := MachineType:Directory;
+ out_msg.Destination.broadcast(MachineType:L1Cache);
+
+ //
+ // Currently the configuration system limits the system to only one
+ // chip. Therefore, if we assume one shared L2 cache, then only one
+ // pertinent L2 cache exist.
+ //
+ //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address));
+
+ out_msg.Destination.add(mapAddressToRange(address,
+ MachineType:L2Cache,
+ l2_select_low_bit,
+ l2_select_num_bits));
+
+ out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.MessageSize := MessageSizeType:Persistent_Control;
+ }
+ starving := false;
+ }
+
+ TBEs.deallocate(address);
+ }
+
+ action(rd_recordDataInTbe, "rd", desc="Record data in TBE") {
+ peek(responseNetwork_in, ResponseMsg) {
+ TBEs[address].DataBlk := in_msg.DataBlk;
+ }
+ }
+
+ action(cd_writeCleanDataToTbe, "cd", desc="Write clean memory data to TBE") {
+ TBEs[address].DataBlk := directory[address].DataBlk;
+ }
+
+ action(dwt_writeDmaDataFromTBE, "dwt", desc="DMA Write data to memory from TBE") {
+ directory[address].DataBlk := TBEs[address].DataBlk;
+ directory[address].DataBlk.copyPartial(TBEs[address].DmaDataBlk, addressOffset(TBEs[address].PhysicalAddress), TBEs[address].Len);
+ }
+
action(f_incrementTokens, "f", desc="Increment the number of tokens we're tracking") {
peek(responseNetwork_in, ResponseMsg) {
assert(in_msg.Tokens >= 1);
@@ -275,14 +692,34 @@ machine(Directory, "Token protocol") {
requestNetwork_in.dequeue();
}
+ action(z_recycleRequest, "z", desc="Recycle the request queue") {
+ requestNetwork_in.recycle();
+ }
+
action(k_popIncomingResponseQueue, "k", desc="Pop incoming response queue") {
responseNetwork_in.dequeue();
}
+ action(kz_recycleResponse, "kz", desc="Recycle incoming response queue") {
+ responseNetwork_in.recycle();
+ }
+
action(l_popIncomingPersistentQueue, "l", desc="Pop incoming persistent queue") {
persistentNetwork_in.dequeue();
}
+ action(p_popDmaRequestQueue, "pd", desc="pop dma request queue") {
+ dmaRequestQueue_in.dequeue();
+ }
+
+ action(y_recycleDmaRequestQueue, "y", desc="recycle dma request queue") {
+ dmaRequestQueue_in.recycle();
+ }
+
+ action(l_popMemQueue, "q", desc="Pop off-chip request queue") {
+ memQueue_in.dequeue();
+ }
+
action(m_writeDataToMemory, "m", desc="Write dirty writeback to memory") {
peek(responseNetwork_in, ResponseMsg) {
directory[in_msg.Address].DataBlk := in_msg.DataBlk;
@@ -291,18 +728,15 @@ machine(Directory, "Token protocol") {
}
}
- action(n_checkIncomingMsg, "n", desc="Check incoming token message") {
+ action(n_checkData, "n", desc="Check incoming clean data message") {
peek(responseNetwork_in, ResponseMsg) {
- assert(in_msg.Type == CoherenceResponseType:ACK_OWNER);
- assert(in_msg.Dirty == false);
- assert(in_msg.MessageSize == MessageSizeType:Writeback_Control);
assert(directory[in_msg.Address].DataBlk == in_msg.DataBlk);
}
}
action(r_bounceResponse, "r", desc="Bounce response to starving processor") {
peek(responseNetwork_in, ResponseMsg) {
- enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency="1") {
out_msg.Address := address;
out_msg.Type := in_msg.Type;
out_msg.Sender := machineID;
@@ -316,7 +750,20 @@ machine(Directory, "Token protocol") {
}
}
- action(s_bounceDatalessOwnerToken, "s", desc="Bounce clean owner token to starving processor") {
+ action(st_scheduleTimeout, "st", desc="Schedule Timeout") {
+ //
+ // currently only support a fixed timeout latency
+ //
+ reissueTimerTable.set(address, fixed_timeout_latency);
+ }
+
+ action(ut_unsetReissueTimer, "ut", desc="Unset reissue timer.") {
+ if (reissueTimerTable.isSet(address)) {
+ reissueTimerTable.unset(address);
+ }
+ }
+
+ action(bd_bounceDatalessOwnerToken, "bd", desc="Bounce clean owner token to starving processor") {
peek(responseNetwork_in, ResponseMsg) {
assert(in_msg.Type == CoherenceResponseType:ACK_OWNER);
assert(in_msg.Dirty == false);
@@ -331,7 +778,7 @@ machine(Directory, "Token protocol") {
// Bounce the message, but "re-associate" the data and the owner
// token. In essence we're converting an ACK_OWNER message to a
// DATA_OWNER message, keeping the number of tokens the same.
- enqueue(responseNetwork_out, ResponseMsg, latency="NULL_LATENCY") {
+ enqueue(responseNetwork_out, ResponseMsg, latency="1") {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:DATA_OWNER;
out_msg.Sender := machineID;
@@ -346,53 +793,212 @@ machine(Directory, "Token protocol") {
}
}
+ action(da_sendDmaAck, "da", desc="Send Ack to DMA controller") {
+ enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") {
+ out_msg.PhysicalAddress := address;
+ out_msg.LineAddress := address;
+ out_msg.Type := DMAResponseType:ACK;
+ out_msg.Destination.add(TBEs[address].DmaRequestor);
+ out_msg.MessageSize := MessageSizeType:Writeback_Control;
+ }
+ }
+
+ action(dm_sendMemoryDataToDma, "dm", desc="Send Data to DMA controller from memory") {
+ peek(memQueue_in, MemoryMsg) {
+ enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") {
+ out_msg.PhysicalAddress := address;
+ out_msg.LineAddress := address;
+ out_msg.Type := DMAResponseType:DATA;
+ //
+ // we send the entire data block and rely on the dma controller to
+ // split it up if need be
+ //
+ out_msg.DataBlk := in_msg.DataBlk;
+ out_msg.Destination.add(TBEs[address].DmaRequestor);
+ out_msg.MessageSize := MessageSizeType:Response_Data;
+ }
+ }
+ }
+
+ action(dd_sendDmaData, "dd", desc="Send Data to DMA controller") {
+ peek(responseNetwork_in, ResponseMsg) {
+ enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") {
+ out_msg.PhysicalAddress := address;
+ out_msg.LineAddress := address;
+ out_msg.Type := DMAResponseType:DATA;
+ //
+ // we send the entire data block and rely on the dma controller to
+ // split it up if need be
+ //
+ out_msg.DataBlk := in_msg.DataBlk;
+ out_msg.Destination.add(TBEs[address].DmaRequestor);
+ out_msg.MessageSize := MessageSizeType:Response_Data;
+ }
+ }
+ }
// TRANSITIONS
- // Trans. from O
- transition(O, GETX, NO) {
- d_sendDataWithAllTokens;
+ //
+ // Trans. from base state O
+ // the directory has valid data
+ //
+ transition(O, GETX, NO_W) {
+ qf_queueMemoryFetchRequest;
j_popIncomingRequestQueue;
}
- transition(O, GETS, NO) {
- d_sendDataWithAllTokens;
+ transition(O, DMA_WRITE, O_DW) {
+ vd_allocateDmaRequestInTBE;
+ bw_broadcastWrite;
+ st_scheduleTimeout;
+ p_popDmaRequestQueue;
+ }
+
+ transition(O, DMA_WRITE_All_Tokens, O_DW_W) {
+ vd_allocateDmaRequestInTBE;
+ cd_writeCleanDataToTbe;
+ dwt_writeDmaDataFromTBE;
+ ld_queueMemoryDmaWriteFromTbe;
+ p_popDmaRequestQueue;
+ }
+
+ transition(O, GETS, NO_W) {
+ qf_queueMemoryFetchRequest;
j_popIncomingRequestQueue;
}
- transition(O, Lockdown, L) {
- dd_sendDataWithAllTokensToStarver;
+ transition(O, DMA_READ, O_DR_W) {
+ vd_allocateDmaRequestInTBE;
+ fd_memoryDma;
+ st_scheduleTimeout;
+ p_popDmaRequestQueue;
+ }
+
+ transition(O, Lockdown, L_W) {
+ qf_queueMemoryFetchRequest;
+ l_popIncomingPersistentQueue;
+ }
+
+ transition(O, {Tokens, Ack_All_Tokens}) {
+ f_incrementTokens;
+ k_popIncomingResponseQueue;
+ }
+
+ transition(O, {Data_Owner, Data_All_Tokens}) {
+ n_checkData;
+ f_incrementTokens;
+ k_popIncomingResponseQueue;
+ }
+
+ //
+ // transitioning to Owner, waiting for memory before DMA ack
+ // All other events should recycle/stall
+ //
+ transition(O_DR_W, Memory_Data, O) {
+ dm_sendMemoryDataToDma;
+ ut_unsetReissueTimer;
+ s_deallocateTBE;
+ l_popMemQueue;
+ }
+
+ //
+ // issued GETX for DMA write, waiting for all tokens
+ //
+ transition(O_DW, Tokens) {
+ f_incrementTokens;
+ k_popIncomingResponseQueue;
+ }
+
+ transition(O_DW, Data_Owner) {
+ f_incrementTokens;
+ rd_recordDataInTbe;
+ k_popIncomingResponseQueue;
+ }
+
+ transition(O_DW, Ack_Owner) {
+ f_incrementTokens;
+ cd_writeCleanDataToTbe;
+ k_popIncomingResponseQueue;
+ }
+
+ transition(O_DW, Lockdown, DW_L) {
l_popIncomingPersistentQueue;
}
- transition(O, Tokens) {
+ transition({NO_DW, O_DW}, Data_All_Tokens, O_DW_W) {
f_incrementTokens;
+ rd_recordDataInTbe;
+ dwt_writeDmaDataFromTBE;
+ ld_queueMemoryDmaWriteFromTbe;
+ ut_unsetReissueTimer;
k_popIncomingResponseQueue;
}
+ transition(O_DW, Ack_All_Tokens, O_DW_W) {
+ f_incrementTokens;
+ dwt_writeDmaDataFromTBE;
+ ld_queueMemoryDmaWriteFromTbe;
+ ut_unsetReissueTimer;
+ k_popIncomingResponseQueue;
+ }
+
+ transition(O_DW, Ack_Owner_All_Tokens, O_DW_W) {
+ f_incrementTokens;
+ cd_writeCleanDataToTbe;
+ dwt_writeDmaDataFromTBE;
+ ld_queueMemoryDmaWriteFromTbe;
+ ut_unsetReissueTimer;
+ k_popIncomingResponseQueue;
+ }
+
+ transition(O_DW_W, Memory_Ack, O) {
+ da_sendDmaAck;
+ s_deallocateTBE;
+ l_popMemQueue;
+ }
+
+ //
// Trans. from NO
+ // The direcotry does not have valid data, but may have some tokens
+ //
transition(NO, GETX) {
a_sendTokens;
j_popIncomingRequestQueue;
}
+ transition(NO, DMA_WRITE, NO_DW) {
+ vd_allocateDmaRequestInTBE;
+ bw_broadcastWrite;
+ st_scheduleTimeout;
+ p_popDmaRequestQueue;
+ }
+
transition(NO, GETS) {
j_popIncomingRequestQueue;
}
+ transition(NO, DMA_READ, NO_DR) {
+ vd_allocateDmaRequestInTBE;
+ br_broadcastRead;
+ st_scheduleTimeout;
+ p_popDmaRequestQueue;
+ }
+
transition(NO, Lockdown, L) {
aa_sendTokensToStarver;
l_popIncomingPersistentQueue;
}
- transition(NO, Data_Owner, O) {
+ transition(NO, {Data_Owner, Data_All_Tokens}, O_W) {
m_writeDataToMemory;
f_incrementTokens;
+ lq_queueMemoryWbRequest;
k_popIncomingResponseQueue;
}
- transition(NO, Ack_Owner, O) {
- n_checkIncomingMsg;
+ transition(NO, {Ack_Owner, Ack_Owner_All_Tokens}, O) {
+ n_checkData;
f_incrementTokens;
k_popIncomingResponseQueue;
}
@@ -402,34 +1008,156 @@ machine(Directory, "Token protocol") {
k_popIncomingResponseQueue;
}
+ transition(NO_W, Memory_Data, NO) {
+ d_sendMemoryDataWithAllTokens;
+ l_popMemQueue;
+ }
+
+ // Trans. from NO_DW
+ transition(NO_DW, Request_Timeout) {
+ ut_unsetReissueTimer;
+ px_tryIssuingPersistentGETXRequest;
+ }
+
+ transition(NO_DW, Lockdown, DW_L) {
+ aa_sendTokensToStarver;
+ l_popIncomingPersistentQueue;
+ }
+
+ // Note: NO_DW, Data_All_Tokens transition is combined with O_DW
+ // Note: NO_DW should not receive the action Ack_All_Tokens because the
+ // directory does not have valid data
+
+ transition(NO_DW, Data_Owner, O_DW) {
+ f_incrementTokens;
+ rd_recordDataInTbe;
+ lq_queueMemoryWbRequest;
+ k_popIncomingResponseQueue;
+ }
+
+ transition({NO_DW, NO_DR}, Tokens) {
+ f_incrementTokens;
+ k_popIncomingResponseQueue;
+ }
+
+ // Trans. from NO_DR
+ transition(NO_DR, Request_Timeout) {
+ ut_unsetReissueTimer;
+ ps_tryIssuingPersistentGETSRequest;
+ }
+
+ transition(NO_DR, Lockdown, DR_L) {
+ aa_sendTokensToStarver;
+ l_popIncomingPersistentQueue;
+ }
+
+ transition(NO_DR, {Data_Owner, Data_All_Tokens}, O_W) {
+ m_writeDataToMemory;
+ f_incrementTokens;
+ dd_sendDmaData;
+ lr_queueMemoryDmaReadWriteback;
+ ut_unsetReissueTimer;
+ s_deallocateTBE;
+ k_popIncomingResponseQueue;
+ }
+
// Trans. from L
- transition(L, {GETX, GETS}) {
+ transition({L, DW_L, DR_L}, {GETX, GETS}) {
j_popIncomingRequestQueue;
}
- transition(L, Lockdown) {
+ transition({L, DW_L, DR_L, L_W, DR_L_W}, Lockdown) {
l_popIncomingPersistentQueue;
}
- // we could change this to write the data to memory and send it cleanly
- transition(L, Data_Owner) {
+ //
+ // Received data for lockdown blocks
+ // For blocks with outstanding dma requests to them
+ // ...we could change this to write the data to memory and send it cleanly
+ // ...we could also proactively complete our DMA requests
+ // However, to keep my mind from spinning out-of-control, we won't for now :)
+ //
+ transition({DW_L, DR_L, L}, {Data_Owner, Data_All_Tokens}) {
r_bounceResponse;
k_popIncomingResponseQueue;
}
- transition(L, Tokens) {
+ transition({DW_L, DR_L, L}, Tokens) {
r_bounceResponse;
k_popIncomingResponseQueue;
}
- transition(L, Ack_Owner) {
- s_bounceDatalessOwnerToken;
+ transition({DW_L, DR_L, L}, {Ack_Owner_All_Tokens, Ack_Owner}) {
+ bd_bounceDatalessOwnerToken;
k_popIncomingResponseQueue;
}
-
transition(L, Unlockdown, NO) {
l_popIncomingPersistentQueue;
}
+ transition(L_W, Memory_Data, L) {
+ dd_sendDataWithAllTokensToStarver;
+ l_popMemQueue;
+ }
+
+ transition(DR_L_W, Memory_Data, DR_L) {
+ dd_sendDataWithAllTokensToStarver;
+ l_popMemQueue;
+ }
+
+ transition(DW_L, {Unlockdown, Own_Lock_or_Unlock}, NO_DW) {
+ l_popIncomingPersistentQueue;
+ }
+
+ transition(DR_L_W, {Unlockdown, Own_Lock_or_Unlock}, O_DR_W) {
+ l_popIncomingPersistentQueue;
+ }
+
+ transition({DW_L, DR_L_W}, Request_Timeout) {
+ ut_unsetReissueTimer;
+ px_tryIssuingPersistentGETXRequest;
+ }
+
+ transition(DR_L, {Unlockdown, Own_Lock_or_Unlock}, NO_DR) {
+ l_popIncomingPersistentQueue;
+ }
+
+ transition(DR_L, Request_Timeout) {
+ ut_unsetReissueTimer;
+ ps_tryIssuingPersistentGETSRequest;
+ }
+
+ transition(O_W, Memory_Ack, O) {
+ l_popMemQueue;
+ }
+
+ transition({O, NO, L, O_DW, NO_DW, NO_DR}, Own_Lock_or_Unlock) {
+ l_popIncomingPersistentQueue;
+ }
+
+ // Blocked states
+ transition({NO_W, O_W, L_W, DR_L_W, O_DW_W, O_DR_W, O_DW, NO_DW, NO_DR}, {GETX, GETS}) {
+ z_recycleRequest;
+ }
+
+ transition({NO_W, O_W, L_W, DR_L_W, O_DW_W, O_DR_W, O_DW, NO_DW, NO_DR, L, DW_L, DR_L}, {DMA_READ, DMA_WRITE}) {
+ y_recycleDmaRequestQueue;
+ }
+
+ transition({NO_W, O_W, L_W, DR_L_W, O_DW_W, O_DR_W}, {Data_Owner, Ack_Owner, Tokens}) {
+ kz_recycleResponse;
+ }
+
+ transition({NO_W, O_W}, Lockdown, L_W) {
+ l_popIncomingPersistentQueue;
+ }
+
+ transition(O_DR_W, Lockdown, DR_L_W) {
+ l_popIncomingPersistentQueue;
+ }
+
+ transition({NO_W, O_W, O_DR_W}, {Unlockdown, Own_Lock_or_Unlock}) {
+ l_popIncomingPersistentQueue;
+ }
}
diff --git a/src/mem/protocol/MOESI_CMP_token-dma.sm b/src/mem/protocol/MOESI_CMP_token-dma.sm
new file mode 100644
index 000000000..550a36ae0
--- /dev/null
+++ b/src/mem/protocol/MOESI_CMP_token-dma.sm
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+machine(DMA, "DMA Controller")
+: int request_latency
+{
+
+ MessageBuffer responseFromDir, network="From", virtual_network="0", ordered="true", no_vector="true";
+ MessageBuffer reqToDirectory, network="To", virtual_network="5", ordered="false", no_vector="true";
+
+ enumeration(State, desc="DMA states", default="DMA_State_READY") {
+ READY, desc="Ready to accept a new request";
+ BUSY_RD, desc="Busy: currently processing a request";
+ BUSY_WR, desc="Busy: currently processing a request";
+ }
+
+ enumeration(Event, desc="DMA events") {
+ ReadRequest, desc="A new read request";
+ WriteRequest, desc="A new write request";
+ Data, desc="Data from a DMA memory read";
+ Ack, desc="DMA write to memory completed";
+ }
+
+ external_type(DMASequencer) {
+ void ackCallback();
+ void dataCallback(DataBlock);
+ }
+
+ MessageBuffer mandatoryQueue, ordered="false", no_vector="true";
+ DMASequencer dma_sequencer, factory='RubySystem::getDMASequencer(m_cfg["dma_sequencer"])', no_vector="true";
+ State cur_state, no_vector="true";
+
+ State getState(Address addr) {
+ return cur_state;
+ }
+ void setState(Address addr, State state) {
+ cur_state := state;
+ }
+
+ out_port(reqToDirectory_out, DMARequestMsg, reqToDirectory, desc="...");
+
+ in_port(dmaRequestQueue_in, SequencerMsg, mandatoryQueue, desc="...") {
+ if (dmaRequestQueue_in.isReady()) {
+ peek(dmaRequestQueue_in, SequencerMsg) {
+ if (in_msg.Type == SequencerRequestType:LD ) {
+ trigger(Event:ReadRequest, in_msg.LineAddress);
+ } else if (in_msg.Type == SequencerRequestType:ST) {
+ trigger(Event:WriteRequest, in_msg.LineAddress);
+ } else {
+ error("Invalid request type");
+ }
+ }
+ }
+ }
+
+ in_port(dmaResponseQueue_in, DMAResponseMsg, responseFromDir, desc="...") {
+ if (dmaResponseQueue_in.isReady()) {
+ peek( dmaResponseQueue_in, DMAResponseMsg) {
+ if (in_msg.Type == DMAResponseType:ACK) {
+ trigger(Event:Ack, in_msg.LineAddress);
+ } else if (in_msg.Type == DMAResponseType:DATA) {
+ trigger(Event:Data, in_msg.LineAddress);
+ } else {
+ error("Invalid response type");
+ }
+ }
+ }
+ }
+
+ action(s_sendReadRequest, "s", desc="Send a DMA read request to memory") {
+ peek(dmaRequestQueue_in, SequencerMsg) {
+ enqueue(reqToDirectory_out, DMARequestMsg, latency=request_latency) {
+ out_msg.PhysicalAddress := in_msg.PhysicalAddress;
+ out_msg.LineAddress := in_msg.LineAddress;
+ out_msg.Type := DMARequestType:READ;
+ out_msg.Requestor := machineID;
+ out_msg.DataBlk := in_msg.DataBlk;
+ out_msg.Len := in_msg.Len;
+ out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.MessageSize := MessageSizeType:Writeback_Control;
+ }
+ }
+ }
+
+ action(s_sendWriteRequest, "\s", desc="Send a DMA write request to memory") {
+ peek(dmaRequestQueue_in, SequencerMsg) {
+ enqueue(reqToDirectory_out, DMARequestMsg, latency=request_latency) {
+ out_msg.PhysicalAddress := in_msg.PhysicalAddress;
+ out_msg.LineAddress := in_msg.LineAddress;
+ out_msg.Type := DMARequestType:WRITE;
+ out_msg.Requestor := machineID;
+ out_msg.DataBlk := in_msg.DataBlk;
+ out_msg.Len := in_msg.Len;
+ out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.MessageSize := MessageSizeType:Writeback_Control;
+ }
+ }
+ }
+
+ action(a_ackCallback, "a", desc="Notify dma controller that write request completed") {
+ peek (dmaResponseQueue_in, DMAResponseMsg) {
+ dma_sequencer.ackCallback();
+ }
+ }
+
+ action(d_dataCallback, "d", desc="Write data to dma sequencer") {
+ peek (dmaResponseQueue_in, DMAResponseMsg) {
+ dma_sequencer.dataCallback(in_msg.DataBlk);
+ }
+ }
+
+ action(p_popRequestQueue, "p", desc="Pop request queue") {
+ dmaRequestQueue_in.dequeue();
+ }
+
+ action(p_popResponseQueue, "\p", desc="Pop request queue") {
+ dmaResponseQueue_in.dequeue();
+ }
+
+ transition(READY, ReadRequest, BUSY_RD) {
+ s_sendReadRequest;
+ p_popRequestQueue;
+ }
+
+ transition(READY, WriteRequest, BUSY_WR) {
+ s_sendWriteRequest;
+ p_popRequestQueue;
+ }
+
+ transition(BUSY_RD, Data, READY) {
+ d_dataCallback;
+ p_popResponseQueue;
+ }
+
+ transition(BUSY_WR, Ack, READY) {
+ a_ackCallback;
+ p_popResponseQueue;
+ }
+}
diff --git a/src/mem/protocol/MOESI_CMP_token-msg.sm b/src/mem/protocol/MOESI_CMP_token-msg.sm
index 2a75ce644..40c16b5e1 100644
--- a/src/mem/protocol/MOESI_CMP_token-msg.sm
+++ b/src/mem/protocol/MOESI_CMP_token-msg.sm
@@ -59,8 +59,10 @@ enumeration(CoherenceResponseType, desc="...") {
// TriggerType
enumeration(TriggerType, desc="...") {
- REQUEST_TIMEOUT, desc="See corresponding event";
+ REQUEST_TIMEOUT, desc="See corresponding event";
USE_TIMEOUT, desc="See corresponding event";
+ DATA, desc="data for dma read response";
+ DATA_ALL_TOKENS, desc="data and all tokens for dma write response";
}
// TriggerMsg
@@ -111,13 +113,45 @@ structure(ResponseMsg, desc="...", interface="NetworkMessage") {
MessageSizeType MessageSize, desc="size category of the message";
}
-GenericRequestType convertToGenericType(CoherenceRequestType type) {
- if(type == CoherenceRequestType:GETS) {
- return GenericRequestType:GETS;
- } else if(type == CoherenceRequestType:GETX) {
- return GenericRequestType:GETX;
- } else {
- DEBUG_EXPR(type);
- error("invalid CoherenceRequestType");
- }
+enumeration(DMARequestType, desc="...", default="DMARequestType_NULL") {
+ READ, desc="Memory Read";
+ WRITE, desc="Memory Write";
+ NULL, desc="Invalid";
}
+
+enumeration(DMAResponseType, desc="...", default="DMAResponseType_NULL") {
+ DATA, desc="DATA read";
+ ACK, desc="ACK write";
+ NULL, desc="Invalid";
+}
+
+structure(DMARequestMsg, desc="...", interface="NetworkMessage") {
+ DMARequestType Type, desc="Request type (read/write)";
+ Address PhysicalAddress, desc="Physical address for this request";
+ Address LineAddress, desc="Line address for this request";
+ MachineID Requestor, desc="Node who initiated the request";
+ NetDest Destination, desc="Destination";
+ DataBlock DataBlk, desc="DataBlk attached to this request";
+ int Len, desc="The length of the request";
+ MessageSizeType MessageSize, desc="size category of the message";
+}
+
+structure(DMAResponseMsg, desc="...", interface="NetworkMessage") {
+ DMAResponseType Type, desc="Response type (DATA/ACK)";
+ Address PhysicalAddress, desc="Physical address for this request";
+ Address LineAddress, desc="Line address for this request";
+ NetDest Destination, desc="Destination";
+ DataBlock DataBlk, desc="DataBlk attached to this request";
+ MessageSizeType MessageSize, desc="size category of the message";
+}
+
+//GenericRequestType convertToGenericType(CoherenceRequestType type) {
+// if(type == CoherenceRequestType:GETS) {
+// return GenericRequestType:GETS;
+// } else if(type == CoherenceRequestType:GETX) {
+// return GenericRequestType:GETX;
+// } else {
+// DEBUG_EXPR(type);
+// error("invalid CoherenceRequestType");
+// }
+//}
diff --git a/src/mem/protocol/MOESI_CMP_token.slicc b/src/mem/protocol/MOESI_CMP_token.slicc
index ae4a6d6ec..a41226f90 100644
--- a/src/mem/protocol/MOESI_CMP_token.slicc
+++ b/src/mem/protocol/MOESI_CMP_token.slicc
@@ -2,4 +2,5 @@ MOESI_CMP_token-msg.sm
MOESI_CMP_token-L1cache.sm
MOESI_CMP_token-L2cache.sm
MOESI_CMP_token-dir.sm
+MOESI_CMP_token-dma.sm
standard_CMP-protocol.sm
diff --git a/src/mem/protocol/MOESI_hammer-cache.sm b/src/mem/protocol/MOESI_hammer-cache.sm
new file mode 100644
index 000000000..3b2240800
--- /dev/null
+++ b/src/mem/protocol/MOESI_hammer-cache.sm
@@ -0,0 +1,1132 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * AMD's contributions to the MOESI hammer protocol do not constitute an
+ * endorsement of its similarity to any AMD products.
+ *
+ * Authors: Milo Martin
+ * Brad Beckmann
+ */
+
+machine(L1Cache, "AMD Hammer-like protocol")
+: int cache_response_latency,
+ int issue_latency
+{
+
+ // NETWORK BUFFERS
+ MessageBuffer requestFromCache, network="To", virtual_network="3", ordered="false";
+ MessageBuffer responseFromCache, network="To", virtual_network="1", ordered="false";
+ MessageBuffer unblockFromCache, network="To", virtual_network="0", ordered="false";
+
+ MessageBuffer forwardToCache, network="From", virtual_network="2", ordered="false";
+ MessageBuffer responseToCache, network="From", virtual_network="1", ordered="false";
+
+
+ // STATES
+ enumeration(State, desc="Cache states", default="L1Cache_State_I") {
+ // Base states
+ I, desc="Idle";
+ S, desc="Shared";
+ O, desc="Owned";
+ M, desc="Modified (dirty)";
+ MM, desc="Modified (dirty and locally modified)";
+
+ // Transient States
+ IM, "IM", desc="Issued GetX";
+ SM, "SM", desc="Issued GetX, we still have an old copy of the line";
+ OM, "OM", desc="Issued GetX, received data";
+ ISM, "ISM", desc="Issued GetX, received data, waiting for all acks";
+ M_W, "M^W", desc="Issued GetS, received exclusive data";
+ MM_W, "MM^W", desc="Issued GetX, received exclusive data";
+ IS, "IS", desc="Issued GetS";
+ SS, "SS", desc="Issued GetS, received data, waiting for all acks";
+ OI, "OI", desc="Issued PutO, waiting for ack";
+ MI, "MI", desc="Issued PutX, waiting for ack";
+ II, "II", desc="Issued PutX/O, saw Other_GETS or Other_GETX, waiting for ack";
+ }
+
+ // EVENTS
+ enumeration(Event, desc="Cache events") {
+ Load, desc="Load request from the processor";
+ Ifetch, desc="I-fetch request from the processor";
+ Store, desc="Store request from the processor";
+ L2_Replacement, desc="L2 Replacement";
+ L1_to_L2, desc="L1 to L2 transfer";
+ L2_to_L1D, desc="L2 to L1-Data transfer";
+ L2_to_L1I, desc="L2 to L1-Instruction transfer";
+
+ // Requests
+ Other_GETX, desc="A GetX from another processor";
+ Other_GETS, desc="A GetS from another processor";
+
+ // Responses
+ Ack, desc="Received an ack message";
+ Shared_Ack, desc="Received an ack message, responder has a shared copy";
+ Data, desc="Received a data message";
+ Shared_Data, desc="Received a data message, responder has a shared copy";
+ Exclusive_Data, desc="Received a data message, responder had an exclusive copy, they gave it to us";
+
+ Writeback_Ack, desc="Writeback O.K. from directory";
+ Writeback_Nack, desc="Writeback not O.K. from directory";
+
+ // Triggers
+ All_acks, desc="Received all required data and message acks";
+ All_acks_no_sharers, desc="Received all acks and no other processor has a shared copy";
+ }
+
+ // TYPES
+
+ // STRUCTURE DEFINITIONS
+
+ MessageBuffer mandatoryQueue, ordered="false";
+ Sequencer sequencer, factory='RubySystem::getSequencer(m_cfg["sequencer"])';
+
+ // CacheEntry
+ structure(Entry, desc="...", interface="AbstractCacheEntry") {
+ State CacheState, desc="cache state";
+ bool Dirty, desc="Is the data dirty (different than memory)?";
+ DataBlock DataBlk, desc="data for the block";
+ }
+
+ // TBE fields
+ structure(TBE, desc="...") {
+ State TBEState, desc="Transient state";
+ DataBlock DataBlk, desc="data for the block, required for concurrent writebacks";
+ bool Dirty, desc="Is the data dirty (different than memory)?";
+ int NumPendingMsgs, desc="Number of acks/data messages that this processor is waiting for";
+ bool Sharers, desc="On a GetS, did we find any other sharers in the system";
+ }
+
+ external_type(CacheMemory) {
+ bool cacheAvail(Address);
+ Address cacheProbe(Address);
+ void allocate(Address, Entry);
+ void deallocate(Address);
+ Entry lookup(Address);
+ void changePermission(Address, AccessPermission);
+ bool isTagPresent(Address);
+ void profileMiss(CacheMsg);
+ }
+
+ external_type(TBETable) {
+ TBE lookup(Address);
+ void allocate(Address);
+ void deallocate(Address);
+ bool isPresent(Address);
+ }
+
+ TBETable TBEs, template_hack="<L1Cache_TBE>";
+ CacheMemory L1IcacheMemory, factory='RubySystem::getCache(m_cfg["icache"])';
+ CacheMemory L1DcacheMemory, factory='RubySystem::getCache(m_cfg["dcache"])';
+ CacheMemory L2cacheMemory, factory='RubySystem::getCache(m_cfg["l2cache"])';
+
+ Entry getCacheEntry(Address addr), return_by_ref="yes" {
+ if (L2cacheMemory.isTagPresent(addr)) {
+ return L2cacheMemory[addr];
+ } else if (L1DcacheMemory.isTagPresent(addr)) {
+ return L1DcacheMemory[addr];
+ } else {
+ return L1IcacheMemory[addr];
+ }
+ }
+
+ void changePermission(Address addr, AccessPermission permission) {
+ if (L2cacheMemory.isTagPresent(addr)) {
+ return L2cacheMemory.changePermission(addr, permission);
+ } else if (L1DcacheMemory.isTagPresent(addr)) {
+ return L1DcacheMemory.changePermission(addr, permission);
+ } else {
+ return L1IcacheMemory.changePermission(addr, permission);
+ }
+ }
+
+ bool isCacheTagPresent(Address addr) {
+ return (L2cacheMemory.isTagPresent(addr) || L1DcacheMemory.isTagPresent(addr) || L1IcacheMemory.isTagPresent(addr));
+ }
+
+ State getState(Address addr) {
+ assert((L1DcacheMemory.isTagPresent(addr) && L1IcacheMemory.isTagPresent(addr)) == false);
+ assert((L1IcacheMemory.isTagPresent(addr) && L2cacheMemory.isTagPresent(addr)) == false);
+ assert((L1DcacheMemory.isTagPresent(addr) && L2cacheMemory.isTagPresent(addr)) == false);
+
+ if(TBEs.isPresent(addr)) {
+ return TBEs[addr].TBEState;
+ } else if (isCacheTagPresent(addr)) {
+ return getCacheEntry(addr).CacheState;
+ }
+ return State:I;
+ }
+
+ void setState(Address addr, State state) {
+ assert((L1DcacheMemory.isTagPresent(addr) && L1IcacheMemory.isTagPresent(addr)) == false);
+ assert((L1IcacheMemory.isTagPresent(addr) && L2cacheMemory.isTagPresent(addr)) == false);
+ assert((L1DcacheMemory.isTagPresent(addr) && L2cacheMemory.isTagPresent(addr)) == false);
+
+ if (TBEs.isPresent(addr)) {
+ TBEs[addr].TBEState := state;
+ }
+
+ if (isCacheTagPresent(addr)) {
+ getCacheEntry(addr).CacheState := state;
+
+ // Set permission
+ if ((state == State:MM) ||
+ (state == State:MM_W)) {
+ changePermission(addr, AccessPermission:Read_Write);
+ } else if (state == State:S ||
+ state == State:O ||
+ state == State:M ||
+ state == State:M_W ||
+ state == State:SM ||
+ state == State:ISM ||
+ state == State:OM ||
+ state == State:SS) {
+ changePermission(addr, AccessPermission:Read_Only);
+ } else {
+ changePermission(addr, AccessPermission:Invalid);
+ }
+ }
+ }
+
+ Event mandatory_request_type_to_event(CacheRequestType type) {
+ if (type == CacheRequestType:LD) {
+ return Event:Load;
+ } else if (type == CacheRequestType:IFETCH) {
+ return Event:Ifetch;
+ } else if ((type == CacheRequestType:ST) || (type == CacheRequestType:ATOMIC)) {
+ return Event:Store;
+ } else {
+ error("Invalid CacheRequestType");
+ }
+ }
+
+ MessageBuffer triggerQueue, ordered="true";
+
+ // ** OUT_PORTS **
+
+ out_port(requestNetwork_out, RequestMsg, requestFromCache);
+ out_port(responseNetwork_out, ResponseMsg, responseFromCache);
+ out_port(unblockNetwork_out, ResponseMsg, unblockFromCache);
+ out_port(triggerQueue_out, TriggerMsg, triggerQueue);
+
+ // ** IN_PORTS **
+
+ // Trigger Queue
+ in_port(triggerQueue_in, TriggerMsg, triggerQueue) {
+ if (triggerQueue_in.isReady()) {
+ peek(triggerQueue_in, TriggerMsg) {
+ if (in_msg.Type == TriggerType:ALL_ACKS) {
+ trigger(Event:All_acks, in_msg.Address);
+ } else if (in_msg.Type == TriggerType:ALL_ACKS_NO_SHARERS) {
+ trigger(Event:All_acks_no_sharers, in_msg.Address);
+ } else {
+ error("Unexpected message");
+ }
+ }
+ }
+ }
+
+ // Nothing from the request network
+
+ // Forward Network
+ in_port(forwardToCache_in, RequestMsg, forwardToCache) {
+ if (forwardToCache_in.isReady()) {
+ peek(forwardToCache_in, RequestMsg) {
+ if (in_msg.Type == CoherenceRequestType:GETX) {
+ trigger(Event:Other_GETX, in_msg.Address);
+ } else if (in_msg.Type == CoherenceRequestType:GETS) {
+ trigger(Event:Other_GETS, in_msg.Address);
+ } else if (in_msg.Type == CoherenceRequestType:WB_ACK) {
+ trigger(Event:Writeback_Ack, in_msg.Address);
+ } else if (in_msg.Type == CoherenceRequestType:WB_NACK) {
+ trigger(Event:Writeback_Nack, in_msg.Address);
+ } else {
+ error("Unexpected message");
+ }
+ }
+ }
+ }
+
+ // Response Network
+ in_port(responseToCache_in, ResponseMsg, responseToCache) {
+ if (responseToCache_in.isReady()) {
+ peek(responseToCache_in, ResponseMsg) {
+ if (in_msg.Type == CoherenceResponseType:ACK) {
+ trigger(Event:Ack, in_msg.Address);
+ } else if (in_msg.Type == CoherenceResponseType:ACK_SHARED) {
+ trigger(Event:Shared_Ack, in_msg.Address);
+ } else if (in_msg.Type == CoherenceResponseType:DATA) {
+ trigger(Event:Data, in_msg.Address);
+ } else if (in_msg.Type == CoherenceResponseType:DATA_SHARED) {
+ trigger(Event:Shared_Data, in_msg.Address);
+ } else if (in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE) {
+ trigger(Event:Exclusive_Data, in_msg.Address);
+ } else {
+ error("Unexpected message");
+ }
+ }
+ }
+ }
+
+ // Nothing from the unblock network
+
+ // Mandatory Queue
+ in_port(mandatoryQueue_in, CacheMsg, mandatoryQueue, desc="...") {
+ if (mandatoryQueue_in.isReady()) {
+ peek(mandatoryQueue_in, CacheMsg) {
+
+ // Check for data access to blocks in I-cache and ifetchs to blocks in D-cache
+
+ if (in_msg.Type == CacheRequestType:IFETCH) {
+ // ** INSTRUCTION ACCESS ***
+
+ // Check to see if it is in the OTHER L1
+ if (L1DcacheMemory.isTagPresent(in_msg.LineAddress)) {
+ // The block is in the wrong L1, try to write it to the L2
+ if (L2cacheMemory.cacheAvail(in_msg.LineAddress)) {
+ trigger(Event:L1_to_L2, in_msg.LineAddress);
+ } else {
+ trigger(Event:L2_Replacement, L2cacheMemory.cacheProbe(in_msg.LineAddress));
+ }
+ }
+
+ if (L1IcacheMemory.isTagPresent(in_msg.LineAddress)) {
+ // The tag matches for the L1, so the L1 fetches the line. We know it can't be in the L2 due to exclusion
+ trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress);
+ } else {
+ if (L1IcacheMemory.cacheAvail(in_msg.LineAddress)) {
+ // L1 does't have the line, but we have space for it in the L1
+ if (L2cacheMemory.isTagPresent(in_msg.LineAddress)) {
+ // L2 has it (maybe not with the right permissions)
+ trigger(Event:L2_to_L1I, in_msg.LineAddress);
+ } else {
+ // We have room, the L2 doesn't have it, so the L1 fetches the line
+ trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress);
+ }
+ } else {
+ // No room in the L1, so we need to make room
+ if (L2cacheMemory.cacheAvail(L1IcacheMemory.cacheProbe(in_msg.LineAddress))) {
+ // The L2 has room, so we move the line from the L1 to the L2
+ trigger(Event:L1_to_L2, L1IcacheMemory.cacheProbe(in_msg.LineAddress));
+ } else {
+ // The L2 does not have room, so we replace a line from the L2
+ trigger(Event:L2_Replacement, L2cacheMemory.cacheProbe(L1IcacheMemory.cacheProbe(in_msg.LineAddress)));
+ }
+ }
+ }
+ } else {
+ // *** DATA ACCESS ***
+
+ // Check to see if it is in the OTHER L1
+ if (L1IcacheMemory.isTagPresent(in_msg.LineAddress)) {
+ // The block is in the wrong L1, try to write it to the L2
+ if (L2cacheMemory.cacheAvail(in_msg.LineAddress)) {
+ trigger(Event:L1_to_L2, in_msg.LineAddress);
+ } else {
+ trigger(Event:L2_Replacement, L2cacheMemory.cacheProbe(in_msg.LineAddress));
+ }
+ }
+
+ if (L1DcacheMemory.isTagPresent(in_msg.LineAddress)) {
+ // The tag matches for the L1, so the L1 fetches the line. We know it can't be in the L2 due to exclusion
+ trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress);
+ } else {
+ if (L1DcacheMemory.cacheAvail(in_msg.LineAddress)) {
+ // L1 does't have the line, but we have space for it in the L1
+ if (L2cacheMemory.isTagPresent(in_msg.LineAddress)) {
+ // L2 has it (maybe not with the right permissions)
+ trigger(Event:L2_to_L1D, in_msg.LineAddress);
+ } else {
+ // We have room, the L2 doesn't have it, so the L1 fetches the line
+ trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress);
+ }
+ } else {
+ // No room in the L1, so we need to make room
+ if (L2cacheMemory.cacheAvail(L1DcacheMemory.cacheProbe(in_msg.LineAddress))) {
+ // The L2 has room, so we move the line from the L1 to the L2
+ trigger(Event:L1_to_L2, L1DcacheMemory.cacheProbe(in_msg.LineAddress));
+ } else {
+ // The L2 does not have room, so we replace a line from the L2
+ trigger(Event:L2_Replacement, L2cacheMemory.cacheProbe(L1DcacheMemory.cacheProbe(in_msg.LineAddress)));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // ACTIONS
+
+ action(a_issueGETS, "a", desc="Issue GETS") {
+ enqueue(requestNetwork_out, RequestMsg, latency=issue_latency) {
+ out_msg.Address := address;
+ out_msg.Type := CoherenceRequestType:GETS;
+ out_msg.Requestor := machineID;
+ out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.MessageSize := MessageSizeType:Request_Control;
+ TBEs[address].NumPendingMsgs := getNumberOfLastLevelCaches(); // One from each other cache (n-1) plus the memory (+1)
+ }
+ }
+
+ action(b_issueGETX, "b", desc="Issue GETX") {
+ enqueue(requestNetwork_out, RequestMsg, latency=issue_latency) {
+ out_msg.Address := address;
+ out_msg.Type := CoherenceRequestType:GETX;
+ out_msg.Requestor := machineID;
+ out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.MessageSize := MessageSizeType:Request_Control;
+ TBEs[address].NumPendingMsgs := getNumberOfLastLevelCaches(); // One from each other cache (n-1) plus the memory (+1)
+ }
+ }
+
+ action(c_sendExclusiveData, "c", desc="Send exclusive data from cache to requestor") {
+ peek(forwardToCache_in, RequestMsg) {
+ enqueue(responseNetwork_out, ResponseMsg, latency=cache_response_latency) {
+ out_msg.Address := address;
+ out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
+ out_msg.Sender := machineID;
+ out_msg.Destination.add(in_msg.Requestor);
+ out_msg.DataBlk := getCacheEntry(address).DataBlk;
+ out_msg.Dirty := getCacheEntry(address).Dirty;
+ out_msg.Acks := 2;
+ out_msg.MessageSize := MessageSizeType:Response_Data;
+ }
+ }
+ }
+
+ action(d_issuePUT, "d", desc="Issue PUT") {
+ enqueue(requestNetwork_out, RequestMsg, latency=issue_latency) {
+ out_msg.Address := address;
+ out_msg.Type := CoherenceRequestType:PUT;
+ out_msg.Requestor := machineID;
+ out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.MessageSize := MessageSizeType:Writeback_Control;
+ }
+ }
+
+ action(e_sendData, "e", desc="Send data from cache to requestor") {
+ peek(forwardToCache_in, RequestMsg) {
+ enqueue(responseNetwork_out, ResponseMsg, latency=cache_response_latency) {
+ out_msg.Address := address;
+ out_msg.Type := CoherenceResponseType:DATA;
+ out_msg.Sender := machineID;
+ out_msg.Destination.add(in_msg.Requestor);
+ out_msg.DataBlk := getCacheEntry(address).DataBlk;
+ out_msg.Dirty := getCacheEntry(address).Dirty;
+ out_msg.Acks := 2;
+ out_msg.MessageSize := MessageSizeType:Response_Data;
+ }
+ }
+ }
+
+ action(ee_sendDataShared, "\e", desc="Send data from cache to requestor, keep a shared copy") {
+ peek(forwardToCache_in, RequestMsg) {
+ enqueue(responseNetwork_out, ResponseMsg, latency=cache_response_latency) {
+ out_msg.Address := address;
+ out_msg.Type := CoherenceResponseType:DATA_SHARED;
+ out_msg.Sender := machineID;
+ out_msg.Destination.add(in_msg.Requestor);
+ out_msg.DataBlk := getCacheEntry(address).DataBlk;
+ out_msg.Dirty := getCacheEntry(address).Dirty;
+ out_msg.Acks := 2;
+ out_msg.MessageSize := MessageSizeType:Response_Data;
+ }
+ }
+ }
+
+ action(f_sendAck, "f", desc="Send ack from cache to requestor") {
+ peek(forwardToCache_in, RequestMsg) {
+ enqueue(responseNetwork_out, ResponseMsg, latency=cache_response_latency) {
+ out_msg.Address := address;
+ out_msg.Type := CoherenceResponseType:ACK;
+ out_msg.Sender := machineID;
+ out_msg.Destination.add(in_msg.Requestor);
+ out_msg.Acks := 1;
+ out_msg.MessageSize := MessageSizeType:Response_Control;
+ }
+ }
+ }
+
+ action(ff_sendAckShared, "\f", desc="Send shared ack from cache to requestor") {
+ peek(forwardToCache_in, RequestMsg) {
+ enqueue(responseNetwork_out, ResponseMsg, latency=cache_response_latency) {
+ out_msg.Address := address;
+ out_msg.Type := CoherenceResponseType:ACK_SHARED;
+ out_msg.Sender := machineID;
+ out_msg.Destination.add(in_msg.Requestor);
+ out_msg.Acks := 1;
+ out_msg.MessageSize := MessageSizeType:Response_Control;
+ }
+ }
+ }
+
+ action(g_sendUnblock, "g", desc="Send unblock to memory") {
+ enqueue(unblockNetwork_out, ResponseMsg, latency=cache_response_latency) {
+ out_msg.Address := address;
+ out_msg.Type := CoherenceResponseType:UNBLOCK;
+ out_msg.Sender := machineID;
+ out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.MessageSize := MessageSizeType:Unblock_Control;
+ }
+ }
+
+ action(h_load_hit, "h", desc="Notify sequencer the load completed.") {
+ DEBUG_EXPR(getCacheEntry(address).DataBlk);
+ sequencer.readCallback(address, getCacheEntry(address).DataBlk);
+ }
+
+ action(hh_store_hit, "\h", desc="Notify sequencer that store completed.") {
+ DEBUG_EXPR(getCacheEntry(address).DataBlk);
+ sequencer.writeCallback(address, getCacheEntry(address).DataBlk);
+ getCacheEntry(address).Dirty := true;
+ }
+
+ action(i_allocateTBE, "i", desc="Allocate TBE") {
+ check_allocate(TBEs);
+ TBEs.allocate(address);
+ TBEs[address].DataBlk := getCacheEntry(address).DataBlk; // Data only used for writebacks
+ TBEs[address].Dirty := getCacheEntry(address).Dirty;
+ TBEs[address].Sharers := false;
+ }
+
+ action(j_popTriggerQueue, "j", desc="Pop trigger queue.") {
+ triggerQueue_in.dequeue();
+ }
+
+ action(k_popMandatoryQueue, "k", desc="Pop mandatory queue.") {
+ mandatoryQueue_in.dequeue();
+ }
+
+ action(l_popForwardQueue, "l", desc="Pop forwareded request queue.") {
+ forwardToCache_in.dequeue();
+ }
+
+ action(m_decrementNumberOfMessages, "m", desc="Decrement the number of messages for which we're waiting") {
+ peek(responseToCache_in, ResponseMsg) {
+ assert(in_msg.Acks > 0);
+ DEBUG_EXPR(TBEs[address].NumPendingMsgs);
+ TBEs[address].NumPendingMsgs := TBEs[address].NumPendingMsgs - in_msg.Acks;
+ DEBUG_EXPR(TBEs[address].NumPendingMsgs);
+ }
+ }
+
+ action(n_popResponseQueue, "n", desc="Pop response queue") {
+ responseToCache_in.dequeue();
+ }
+
+ action(o_checkForCompletion, "o", desc="Check if we have received all the messages required for completion") {
+ if (TBEs[address].NumPendingMsgs == 0) {
+ enqueue(triggerQueue_out, TriggerMsg) {
+ out_msg.Address := address;
+ if (TBEs[address].Sharers) {
+ out_msg.Type := TriggerType:ALL_ACKS;
+ } else {
+ out_msg.Type := TriggerType:ALL_ACKS_NO_SHARERS;
+ }
+ }
+ }
+ }
+
+ action(p_decrementNumberOfMessagesByOne, "p", desc="Decrement the number of messages for which we're waiting by one") {
+ TBEs[address].NumPendingMsgs := TBEs[address].NumPendingMsgs - 1;
+ }
+
+ action(pp_incrementNumberOfMessagesByOne, "\p", desc="Increment the number of messages for which we're waiting by one") {
+ TBEs[address].NumPendingMsgs := TBEs[address].NumPendingMsgs + 1;
+ }
+
+ action(q_sendDataFromTBEToCache, "q", desc="Send data from TBE to cache") {
+ peek(forwardToCache_in, RequestMsg) {
+ enqueue(responseNetwork_out, ResponseMsg, latency=cache_response_latency) {
+ out_msg.Address := address;
+ out_msg.Type := CoherenceResponseType:DATA;
+ out_msg.Sender := machineID;
+ out_msg.Destination.add(in_msg.Requestor);
+ out_msg.DataBlk := TBEs[address].DataBlk;
+ out_msg.Dirty := TBEs[address].Dirty;
+ out_msg.Acks := 2;
+ out_msg.MessageSize := MessageSizeType:Response_Data;
+ }
+ }
+ }
+
+ action(qq_sendDataFromTBEToMemory, "\q", desc="Send data from TBE to memory") {
+ enqueue(unblockNetwork_out, ResponseMsg, latency=cache_response_latency) {
+ out_msg.Address := address;
+ out_msg.Sender := machineID;
+ out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.Dirty := TBEs[address].Dirty;
+ if (TBEs[address].Dirty) {
+ out_msg.Type := CoherenceResponseType:WB_DIRTY;
+ out_msg.DataBlk := TBEs[address].DataBlk;
+ out_msg.MessageSize := MessageSizeType:Writeback_Data;
+ } else {
+ out_msg.Type := CoherenceResponseType:WB_CLEAN;
+ // NOTE: in a real system this would not send data. We send
+ // data here only so we can check it at the memory
+ out_msg.DataBlk := TBEs[address].DataBlk;
+ out_msg.MessageSize := MessageSizeType:Writeback_Control;
+ }
+ }
+ }
+
+ action(r_setSharerBit, "r", desc="We saw other sharers") {
+ TBEs[address].Sharers := true;
+ }
+
+ action(s_deallocateTBE, "s", desc="Deallocate TBE") {
+ TBEs.deallocate(address);
+ }
+
+ action(t_sendExclusiveDataFromTBEToMemory, "t", desc="Send exclusive data from TBE to memory") {
+ enqueue(unblockNetwork_out, ResponseMsg, latency=cache_response_latency) {
+ out_msg.Address := address;
+ out_msg.Sender := machineID;
+ out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.DataBlk := TBEs[address].DataBlk;
+ out_msg.Dirty := TBEs[address].Dirty;
+ if (TBEs[address].Dirty) {
+ out_msg.Type := CoherenceResponseType:WB_EXCLUSIVE_DIRTY;
+ out_msg.DataBlk := TBEs[address].DataBlk;
+ out_msg.MessageSize := MessageSizeType:Writeback_Data;
+ } else {
+ out_msg.Type := CoherenceResponseType:WB_EXCLUSIVE_CLEAN;
+ // NOTE: in a real system this would not send data. We send
+ // data here only so we can check it at the memory
+ out_msg.DataBlk := TBEs[address].DataBlk;
+ out_msg.MessageSize := MessageSizeType:Writeback_Control;
+ }
+ }
+ }
+
+ action(u_writeDataToCache, "u", desc="Write data to cache") {
+ peek(responseToCache_in, ResponseMsg) {
+ getCacheEntry(address).DataBlk := in_msg.DataBlk;
+ getCacheEntry(address).Dirty := in_msg.Dirty;
+ }
+ }
+
+ action(v_writeDataToCacheVerify, "v", desc="Write data to cache, assert it was same as before") {
+ peek(responseToCache_in, ResponseMsg) {
+ assert(getCacheEntry(address).DataBlk == in_msg.DataBlk);
+ getCacheEntry(address).DataBlk := in_msg.DataBlk;
+ getCacheEntry(address).Dirty := in_msg.Dirty;
+ }
+ }
+
+ action(gg_deallocateL1CacheBlock, "\g", desc="Deallocate cache block. Sets the cache to invalid, allowing a replacement in parallel with a fetch.") {
+ if (L1DcacheMemory.isTagPresent(address)) {
+ L1DcacheMemory.deallocate(address);
+ } else {
+ L1IcacheMemory.deallocate(address);
+ }
+ }
+
+ action(ii_allocateL1DCacheBlock, "\i", desc="Set L1 D-cache tag equal to tag of block B.") {
+ if (L1DcacheMemory.isTagPresent(address) == false) {
+ L1DcacheMemory.allocate(address, new Entry);
+ }
+ }
+
+ action(jj_allocateL1ICacheBlock, "\j", desc="Set L1 I-cache tag equal to tag of block B.") {
+ if (L1IcacheMemory.isTagPresent(address) == false) {
+ L1IcacheMemory.allocate(address, new Entry);
+ }
+ }
+
+ action(vv_allocateL2CacheBlock, "\v", desc="Set L2 cache tag equal to tag of block B.") {
+ L2cacheMemory.allocate(address, new Entry);
+ }
+
+ action(rr_deallocateL2CacheBlock, "\r", desc="Deallocate L2 cache block. Sets the cache to not present, allowing a replacement in parallel with a fetch.") {
+ L2cacheMemory.deallocate(address);
+ }
+
+ action(ss_copyFromL1toL2, "\s", desc="Copy data block from L1 (I or D) to L2") {
+ if (L1DcacheMemory.isTagPresent(address)) {
+ L2cacheMemory[address] := L1DcacheMemory[address];
+ } else {
+ L2cacheMemory[address] := L1IcacheMemory[address];
+ }
+ }
+
+ action(tt_copyFromL2toL1, "\t", desc="Copy data block from L2 to L1 (I or D)") {
+ if (L1DcacheMemory.isTagPresent(address)) {
+ L1DcacheMemory[address] := L2cacheMemory[address];
+ } else {
+ L1IcacheMemory[address] := L2cacheMemory[address];
+ }
+ }
+
+ action(uu_profileMiss, "\u", desc="Profile the demand miss") {
+ peek(mandatoryQueue_in, CacheMsg) {
+ if (L1IcacheMemory.isTagPresent(address)) {
+ L1IcacheMemory.profileMiss(in_msg);
+ } else if (L1DcacheMemory.isTagPresent(address)) {
+ L1DcacheMemory.profileMiss(in_msg);
+ } else {
+ L2cacheMemory.profileMiss(in_msg);
+ }
+ }
+ }
+
+ action(zz_recycleMandatoryQueue, "\z", desc="Send the head of the mandatory queue to the back of the queue.") {
+ mandatoryQueue_in.recycle();
+ }
+
+ //*****************************************************
+ // TRANSITIONS
+ //*****************************************************
+
+ // Transitions for Load/Store/L2_Replacement from transient states
+ transition({IM, SM, ISM, OM, IS, SS, OI, MI, II}, {Store, L2_Replacement}) {
+ zz_recycleMandatoryQueue;
+ }
+
+ transition({M_W, MM_W}, {L2_Replacement}) {
+ zz_recycleMandatoryQueue;
+ }
+
+ transition({IM, IS, OI, MI, II}, {Load, Ifetch}) {
+ zz_recycleMandatoryQueue;
+ }
+
+ transition({IM, SM, ISM, OM, IS, SS, MM_W, M_W, OI, MI, II}, L1_to_L2) {
+ zz_recycleMandatoryQueue;
+ }
+
+ // Transitions moving data between the L1 and L2 caches
+ transition({I, S, O, M, MM}, L1_to_L2) {
+ vv_allocateL2CacheBlock;
+ ss_copyFromL1toL2; // Not really needed for state I
+ gg_deallocateL1CacheBlock;
+ }
+
+ transition({I, S, O, M, MM}, L2_to_L1D) {
+ ii_allocateL1DCacheBlock;
+ tt_copyFromL2toL1; // Not really needed for state I
+ rr_deallocateL2CacheBlock;
+ }
+
+ transition({I, S, O, M, MM}, L2_to_L1I) {
+ jj_allocateL1ICacheBlock;
+ tt_copyFromL2toL1; // Not really needed for state I
+ rr_deallocateL2CacheBlock;
+ }
+
+ // Transitions from Idle
+ transition(I, Load, IS) {
+ ii_allocateL1DCacheBlock;
+ i_allocateTBE;
+ a_issueGETS;
+ uu_profileMiss;
+ k_popMandatoryQueue;
+ }
+
+ transition(I, Ifetch, IS) {
+ jj_allocateL1ICacheBlock;
+ i_allocateTBE;
+ a_issueGETS;
+ uu_profileMiss;
+ k_popMandatoryQueue;
+ }
+
+ transition(I, Store, IM) {
+ ii_allocateL1DCacheBlock;
+ i_allocateTBE;
+ b_issueGETX;
+ uu_profileMiss;
+ k_popMandatoryQueue;
+ }
+
+ transition(I, L2_Replacement) {
+ rr_deallocateL2CacheBlock;
+ }
+
+ transition(I, {Other_GETX, Other_GETS}) {
+ f_sendAck;
+ l_popForwardQueue;
+ }
+
+ // Transitions from Shared
+ transition({S, SM, ISM}, {Load, Ifetch}) {
+ h_load_hit;
+ k_popMandatoryQueue;
+ }
+
+ transition(S, Store, SM) {
+ i_allocateTBE;
+ b_issueGETX;
+ uu_profileMiss;
+ k_popMandatoryQueue;
+ }
+
+ transition(S, L2_Replacement, I) {
+ rr_deallocateL2CacheBlock;
+ }
+
+ transition(S, Other_GETX, I) {
+ f_sendAck;
+ l_popForwardQueue;
+ }
+
+ transition(S, Other_GETS) {
+ ff_sendAckShared;
+ l_popForwardQueue;
+ }
+
+ // Transitions from Owned
+ transition({O, OM, SS, MM_W, M_W}, {Load, Ifetch}) {
+ h_load_hit;
+ k_popMandatoryQueue;
+ }
+
+ transition(O, Store, OM) {
+ i_allocateTBE;
+ b_issueGETX;
+ p_decrementNumberOfMessagesByOne;
+ uu_profileMiss;
+ k_popMandatoryQueue;
+ }
+
+ transition(O, L2_Replacement, OI) {
+ i_allocateTBE;
+ d_issuePUT;
+ rr_deallocateL2CacheBlock;
+ }
+
+ transition(O, Other_GETX, I) {
+ e_sendData;
+ l_popForwardQueue;
+ }
+
+ transition(O, Other_GETS) {
+ ee_sendDataShared;
+ l_popForwardQueue;
+ }
+
+ // Transitions from Modified
+ transition(MM, {Load, Ifetch}) {
+ h_load_hit;
+ k_popMandatoryQueue;
+ }
+
+ transition(MM, Store) {
+ hh_store_hit;
+ k_popMandatoryQueue;
+ }
+
+ transition(MM, L2_Replacement, MI) {
+ i_allocateTBE;
+ d_issuePUT;
+ rr_deallocateL2CacheBlock;
+ }
+
+ transition(MM, Other_GETX, I) {
+ c_sendExclusiveData;
+ l_popForwardQueue;
+ }
+
+ transition(MM, Other_GETS, I) {
+ c_sendExclusiveData;
+ l_popForwardQueue;
+ }
+
+ // Transitions from Dirty Exclusive
+ transition(M, {Load, Ifetch}) {
+ h_load_hit;
+ k_popMandatoryQueue;
+ }
+
+ transition(M, Store, MM) {
+ hh_store_hit;
+ k_popMandatoryQueue;
+ }
+
+ transition(M, L2_Replacement, MI) {
+ i_allocateTBE;
+ d_issuePUT;
+ rr_deallocateL2CacheBlock;
+ }
+
+ transition(M, Other_GETX, I) {
+ c_sendExclusiveData;
+ l_popForwardQueue;
+ }
+
+ transition(M, Other_GETS, O) {
+ ee_sendDataShared;
+ l_popForwardQueue;
+ }
+
+ // Transitions from IM
+
+ transition(IM, {Other_GETX, Other_GETS}) {
+ f_sendAck;
+ l_popForwardQueue;
+ }
+
+ transition(IM, Ack) {
+ m_decrementNumberOfMessages;
+ o_checkForCompletion;
+ n_popResponseQueue;
+ }
+
+ transition(IM, Data, ISM) {
+ u_writeDataToCache;
+ m_decrementNumberOfMessages;
+ o_checkForCompletion;
+ n_popResponseQueue;
+ }
+
+ transition(IM, Exclusive_Data, MM_W) {
+ u_writeDataToCache;
+ m_decrementNumberOfMessages;
+ o_checkForCompletion;
+ hh_store_hit;
+ n_popResponseQueue;
+ }
+
+ // Transitions from SM
+ transition(SM, Other_GETS) {
+ ff_sendAckShared;
+ l_popForwardQueue;
+ }
+
+ transition(SM, Other_GETX, IM) {
+ f_sendAck;
+ l_popForwardQueue;
+ }
+
+ transition(SM, Ack) {
+ m_decrementNumberOfMessages;
+ o_checkForCompletion;
+ n_popResponseQueue;
+ }
+
+ transition(SM, Data, ISM) {
+ v_writeDataToCacheVerify;
+ m_decrementNumberOfMessages;
+ o_checkForCompletion;
+ n_popResponseQueue;
+ }
+
+ // Transitions from ISM
+ transition(ISM, Ack) {
+ m_decrementNumberOfMessages;
+ o_checkForCompletion;
+ n_popResponseQueue;
+ }
+
+ transition(ISM, All_acks_no_sharers, MM) {
+ hh_store_hit;
+ g_sendUnblock;
+ s_deallocateTBE;
+ j_popTriggerQueue;
+ }
+
+ // Transitions from OM
+
+ transition(OM, Other_GETX, IM) {
+ e_sendData;
+ pp_incrementNumberOfMessagesByOne;
+ l_popForwardQueue;
+ }
+
+ transition(OM, Other_GETS) {
+ ee_sendDataShared;
+ l_popForwardQueue;
+ }
+
+ transition(OM, Ack) {
+ m_decrementNumberOfMessages;
+ o_checkForCompletion;
+ n_popResponseQueue;
+ }
+
+ transition(OM, {All_acks, All_acks_no_sharers}, MM) {
+ hh_store_hit;
+ g_sendUnblock;
+ s_deallocateTBE;
+ j_popTriggerQueue;
+ }
+
+ // Transitions from IS
+
+ transition(IS, {Other_GETX, Other_GETS}) {
+ f_sendAck;
+ l_popForwardQueue;
+ }
+
+ transition(IS, Ack) {
+ m_decrementNumberOfMessages;
+ o_checkForCompletion;
+ n_popResponseQueue;
+ }
+
+ transition(IS, Shared_Ack) {
+ m_decrementNumberOfMessages;
+ r_setSharerBit;
+ o_checkForCompletion;
+ n_popResponseQueue;
+ }
+
+ transition(IS, Data, SS) {
+ u_writeDataToCache;
+ m_decrementNumberOfMessages;
+ o_checkForCompletion;
+ h_load_hit;
+ n_popResponseQueue;
+ }
+
+ transition(IS, Exclusive_Data, M_W) {
+ u_writeDataToCache;
+ m_decrementNumberOfMessages;
+ o_checkForCompletion;
+ h_load_hit;
+ n_popResponseQueue;
+ }
+
+ transition(IS, Shared_Data, SS) {
+ u_writeDataToCache;
+ r_setSharerBit;
+ m_decrementNumberOfMessages;
+ o_checkForCompletion;
+ h_load_hit;
+ n_popResponseQueue;
+ }
+
+ // Transitions from SS
+
+ transition(SS, Ack) {
+ m_decrementNumberOfMessages;
+ o_checkForCompletion;
+ n_popResponseQueue;
+ }
+
+ transition(SS, Shared_Ack) {
+ m_decrementNumberOfMessages;
+ r_setSharerBit;
+ o_checkForCompletion;
+ n_popResponseQueue;
+ }
+
+ transition(SS, All_acks, S) {
+ g_sendUnblock;
+ s_deallocateTBE;
+ j_popTriggerQueue;
+ }
+
+ transition(SS, All_acks_no_sharers, S) {
+ // Note: The directory might still be the owner, so that is why we go to S
+ g_sendUnblock;
+ s_deallocateTBE;
+ j_popTriggerQueue;
+ }
+
+ // Transitions from MM_W
+
+ transition(MM_W, Store) {
+ hh_store_hit;
+ k_popMandatoryQueue;
+ }
+
+ transition(MM_W, Ack) {
+ m_decrementNumberOfMessages;
+ o_checkForCompletion;
+ n_popResponseQueue;
+ }
+
+ transition(MM_W, All_acks_no_sharers, MM) {
+ g_sendUnblock;
+ s_deallocateTBE;
+ j_popTriggerQueue;
+ }
+
+ // Transitions from M_W
+
+ transition(M_W, Store, MM_W) {
+ hh_store_hit;
+ k_popMandatoryQueue;
+ }
+
+ transition(M_W, Ack) {
+ m_decrementNumberOfMessages;
+ o_checkForCompletion;
+ n_popResponseQueue;
+ }
+
+ transition(M_W, All_acks_no_sharers, M) {
+ g_sendUnblock;
+ s_deallocateTBE;
+ j_popTriggerQueue;
+ }
+
+ // Transitions from OI/MI
+
+ transition({OI, MI}, Other_GETX, II) {
+ q_sendDataFromTBEToCache;
+ l_popForwardQueue;
+ }
+
+ transition({OI, MI}, Other_GETS, OI) {
+ q_sendDataFromTBEToCache;
+ l_popForwardQueue;
+ }
+
+ transition(MI, Writeback_Ack, I) {
+ t_sendExclusiveDataFromTBEToMemory;
+ s_deallocateTBE;
+ l_popForwardQueue;
+ }
+
+ transition(OI, Writeback_Ack, I) {
+ qq_sendDataFromTBEToMemory;
+ s_deallocateTBE;
+ l_popForwardQueue;
+ }
+
+ // Transitions from II
+ transition(II, {Other_GETS, Other_GETX}, II) {
+ f_sendAck;
+ l_popForwardQueue;
+ }
+
+ transition(II, Writeback_Ack, I) {
+ g_sendUnblock;
+ s_deallocateTBE;
+ l_popForwardQueue;
+ }
+
+ transition(II, Writeback_Nack, I) {
+ s_deallocateTBE;
+ l_popForwardQueue;
+ }
+}
+
diff --git a/src/mem/protocol/MOESI_hammer-dir.sm b/src/mem/protocol/MOESI_hammer-dir.sm
new file mode 100644
index 000000000..b9b001e40
--- /dev/null
+++ b/src/mem/protocol/MOESI_hammer-dir.sm
@@ -0,0 +1,920 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2009 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * AMD's contributions to the MOESI hammer protocol do not constitute an
+ * endorsement of its similarity to any AMD products.
+ *
+ * Authors: Milo Martin
+ * Brad Beckmann
+ */
+
+machine(Directory, "AMD Hammer-like protocol")
+: int memory_controller_latency
+{
+
+ MessageBuffer forwardFromDir, network="To", virtual_network="2", ordered="false";
+ MessageBuffer responseFromDir, network="To", virtual_network="1", ordered="false";
+ //
+ // For a finite buffered network, note that the DMA response network only
+ // works at this relatively higher numbered (lower priority) virtual network
+ // because the trigger queue decouples cache responses from DMA responses.
+ //
+ MessageBuffer dmaResponseFromDir, network="To", virtual_network="4", ordered="true";
+
+ MessageBuffer unblockToDir, network="From", virtual_network="0", ordered="false";
+ MessageBuffer responseToDir, network="From", virtual_network="1", ordered="false";
+ MessageBuffer requestToDir, network="From", virtual_network="3", ordered="false";
+ MessageBuffer dmaRequestToDir, network="From", virtual_network="5", ordered="true";
+
+ // STATES
+ enumeration(State, desc="Directory states", default="Directory_State_E") {
+ // Base states
+ NO, desc="Not Owner";
+ O, desc="Owner";
+ E, desc="Exclusive Owner (we can provide the data in exclusive)";
+ NO_B, "NO^B", desc="Not Owner, Blocked";
+ O_B, "O^B", desc="Owner, Blocked";
+ NO_B_W, desc="Not Owner, Blocked, waiting for Dram";
+ O_B_W, desc="Owner, Blocked, waiting for Dram";
+ NO_W, desc="Not Owner, waiting for Dram";
+ O_W, desc="Owner, waiting for Dram";
+ NO_DW_B_W, desc="Not Owner, Dma Write waiting for Dram and cache responses";
+ NO_DR_B_W, desc="Not Owner, Dma Read waiting for Dram and cache responses";
+ NO_DR_B_D, desc="Not Owner, Dma Read waiting for cache responses including dirty data";
+ NO_DR_B, desc="Not Owner, Dma Read waiting for cache responses";
+ NO_DW_W, desc="Not Owner, Dma Write waiting for Dram";
+ O_DR_B_W, desc="Owner, Dma Read waiting for Dram and cache responses";
+ O_DR_B, desc="Owner, Dma Read waiting for cache responses";
+ WB, desc="Blocked on a writeback";
+ WB_O_W, desc="Blocked on memory write, will go to O";
+ WB_E_W, desc="Blocked on memory write, will go to E";
+ }
+
+ // Events
+ enumeration(Event, desc="Directory events") {
+ GETX, desc="A GETX arrives";
+ GETS, desc="A GETS arrives";
+ PUT, desc="A PUT arrives";
+ Unblock, desc="An unblock message arrives";
+ Writeback_Clean, desc="The final part of a PutX (no data)";
+ Writeback_Dirty, desc="The final part of a PutX (data)";
+ Writeback_Exclusive_Clean, desc="The final part of a PutX (no data, exclusive)";
+ Writeback_Exclusive_Dirty, desc="The final part of a PutX (data, exclusive)";
+
+ // DMA requests
+ DMA_READ, desc="A DMA Read memory request";
+ DMA_WRITE, desc="A DMA Write memory request";
+
+ // Memory Controller
+ Memory_Data, desc="Fetched data from memory arrives";
+ Memory_Ack, desc="Writeback Ack from memory arrives";
+
+ // Cache responses required to handle DMA
+ Ack, desc="Received an ack message";
+ Shared_Ack, desc="Received an ack message, responder has a shared copy";
+ Shared_Data, desc="Received a data message, responder has a shared copy";
+ Exclusive_Data, desc="Received a data message, responder had an exclusive copy, they gave it to us";
+
+ // Triggers
+ All_acks_and_data, desc="Received all required data and message acks";
+ All_acks_and_data_no_sharers, desc="Received all acks and no other processor has a shared copy";
+ }
+
+ // TYPES
+
+ // DirectoryEntry
+ structure(Entry, desc="...") {
+ State DirectoryState, desc="Directory state";
+ DataBlock DataBlk, desc="data for the block";
+ }
+
+ external_type(DirectoryMemory) {
+ Entry lookup(Address);
+ bool isPresent(Address);
+ }
+
+ external_type(MemoryControl, inport="yes", outport="yes") {
+
+ }
+
+ // TBE entries for DMA requests
+ structure(TBE, desc="TBE entries for outstanding DMA requests") {
+ Address PhysicalAddress, desc="physical address";
+ State TBEState, desc="Transient State";
+ CoherenceResponseType ResponseType, desc="The type for the subsequent response message";
+ DataBlock DmaDataBlk, desc="DMA Data to be written. Partial blocks need to merged with system memory";
+ DataBlock DataBlk, desc="The current view of system memory";
+ int Len, desc="...";
+ MachineID DmaRequestor, desc="DMA requestor";
+ int NumPendingMsgs, desc="Number of pending acks/messages";
+ bool CacheDirty, desc="Indicates whether a cache has responded with dirty data";
+ bool Sharers, desc="Indicates whether a cache has indicated it is currently a sharer";
+ }
+
+ external_type(TBETable) {
+ TBE lookup(Address);
+ void allocate(Address);
+ void deallocate(Address);
+ bool isPresent(Address);
+ }
+
+ // ** OBJECTS **
+
+ DirectoryMemory directory, factory='RubySystem::getDirectory(m_cfg["directory_name"])';
+
+ MemoryControl memBuffer, factory='RubySystem::getMemoryControl(m_cfg["memory_controller_name"])';
+
+ TBETable TBEs, template_hack="<Directory_TBE>";
+
+ State getState(Address addr) {
+ if (TBEs.isPresent(addr)) {
+ return TBEs[addr].TBEState;
+ } else {
+ return directory[addr].DirectoryState;
+ }
+ }
+
+ void setState(Address addr, State state) {
+ if (TBEs.isPresent(addr)) {
+ TBEs[addr].TBEState := state;
+ }
+ directory[addr].DirectoryState := state;
+ }
+
+ MessageBuffer triggerQueue, ordered="true";
+
+ // ** OUT_PORTS **
+ out_port(requestQueue_out, ResponseMsg, requestToDir); // For recycling requests
+ out_port(forwardNetwork_out, RequestMsg, forwardFromDir);
+ out_port(responseNetwork_out, ResponseMsg, responseFromDir);
+ out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir);
+ out_port(triggerQueue_out, TriggerMsg, triggerQueue);
+
+ //
+ // Memory buffer for memory controller to DIMM communication
+ //
+ out_port(memQueue_out, MemoryMsg, memBuffer);
+
+ // ** IN_PORTS **
+
+ // Trigger Queue
+ in_port(triggerQueue_in, TriggerMsg, triggerQueue) {
+ if (triggerQueue_in.isReady()) {
+ peek(triggerQueue_in, TriggerMsg) {
+ if (in_msg.Type == TriggerType:ALL_ACKS) {
+ trigger(Event:All_acks_and_data, in_msg.Address);
+ } else if (in_msg.Type == TriggerType:ALL_ACKS_NO_SHARERS) {
+ trigger(Event:All_acks_and_data_no_sharers, in_msg.Address);
+ } else {
+ error("Unexpected message");
+ }
+ }
+ }
+ }
+
+ in_port(unblockNetwork_in, ResponseMsg, unblockToDir) {
+ if (unblockNetwork_in.isReady()) {
+ peek(unblockNetwork_in, ResponseMsg) {
+ if (in_msg.Type == CoherenceResponseType:UNBLOCK) {
+ trigger(Event:Unblock, in_msg.Address);
+ } else if (in_msg.Type == CoherenceResponseType:WB_CLEAN) {
+ trigger(Event:Writeback_Clean, in_msg.Address);
+ } else if (in_msg.Type == CoherenceResponseType:WB_DIRTY) {
+ trigger(Event:Writeback_Dirty, in_msg.Address);
+ } else if (in_msg.Type == CoherenceResponseType:WB_EXCLUSIVE_CLEAN) {
+ trigger(Event:Writeback_Exclusive_Clean, in_msg.Address);
+ } else if (in_msg.Type == CoherenceResponseType:WB_EXCLUSIVE_DIRTY) {
+ trigger(Event:Writeback_Exclusive_Dirty, in_msg.Address);
+ } else {
+ error("Invalid message");
+ }
+ }
+ }
+ }
+
+ // Response Network
+ in_port(responseToDir_in, ResponseMsg, responseToDir) {
+ if (responseToDir_in.isReady()) {
+ peek(responseToDir_in, ResponseMsg) {
+ if (in_msg.Type == CoherenceResponseType:ACK) {
+ trigger(Event:Ack, in_msg.Address);
+ } else if (in_msg.Type == CoherenceResponseType:ACK_SHARED) {
+ trigger(Event:Shared_Ack, in_msg.Address);
+ } else if (in_msg.Type == CoherenceResponseType:DATA_SHARED) {
+ trigger(Event:Shared_Data, in_msg.Address);
+ } else if (in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE) {
+ trigger(Event:Exclusive_Data, in_msg.Address);
+ } else {
+ error("Unexpected message");
+ }
+ }
+ }
+ }
+
+ in_port(dmaRequestQueue_in, DMARequestMsg, dmaRequestToDir) {
+ if (dmaRequestQueue_in.isReady()) {
+ peek(dmaRequestQueue_in, DMARequestMsg) {
+ if (in_msg.Type == DMARequestType:READ) {
+ trigger(Event:DMA_READ, in_msg.LineAddress);
+ } else if (in_msg.Type == DMARequestType:WRITE) {
+ trigger(Event:DMA_WRITE, in_msg.LineAddress);
+ } else {
+ error("Invalid message");
+ }
+ }
+ }
+ }
+
+ in_port(requestQueue_in, RequestMsg, requestToDir) {
+ if (requestQueue_in.isReady()) {
+ peek(requestQueue_in, RequestMsg) {
+ if (in_msg.Type == CoherenceRequestType:GETS) {
+ trigger(Event:GETS, in_msg.Address);
+ } else if (in_msg.Type == CoherenceRequestType:GETX) {
+ trigger(Event:GETX, in_msg.Address);
+ } else if (in_msg.Type == CoherenceRequestType:PUT) {
+ trigger(Event:PUT, in_msg.Address);
+ } else {
+ error("Invalid message");
+ }
+ }
+ }
+ }
+
+ // off-chip memory request/response is done
+ in_port(memQueue_in, MemoryMsg, memBuffer) {
+ if (memQueue_in.isReady()) {
+ peek(memQueue_in, MemoryMsg) {
+ if (in_msg.Type == MemoryRequestType:MEMORY_READ) {
+ trigger(Event:Memory_Data, in_msg.Address);
+ } else if (in_msg.Type == MemoryRequestType:MEMORY_WB) {
+ trigger(Event:Memory_Ack, in_msg.Address);
+ } else {
+ DEBUG_EXPR(in_msg.Type);
+ error("Invalid message");
+ }
+ }
+ }
+ }
+
+ // Actions
+
+ action(a_sendWriteBackAck, "a", desc="Send writeback ack to requestor") {
+ peek(requestQueue_in, RequestMsg) {
+ enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) {
+ out_msg.Address := address;
+ out_msg.Type := CoherenceRequestType:WB_ACK;
+ out_msg.Requestor := in_msg.Requestor;
+ out_msg.Destination.add(in_msg.Requestor);
+ out_msg.MessageSize := MessageSizeType:Writeback_Control;
+ }
+ }
+ }
+
+ action(b_sendWriteBackNack, "b", desc="Send writeback nack to requestor") {
+ peek(requestQueue_in, RequestMsg) {
+ enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) {
+ out_msg.Address := address;
+ out_msg.Type := CoherenceRequestType:WB_NACK;
+ out_msg.Requestor := in_msg.Requestor;
+ out_msg.Destination.add(in_msg.Requestor);
+ out_msg.MessageSize := MessageSizeType:Writeback_Control;
+ }
+ }
+ }
+
+ action(v_allocateTBE, "v", desc="Allocate TBE") {
+ peek(requestQueue_in, RequestMsg) {
+ TBEs.allocate(address);
+ TBEs[address].PhysicalAddress := address;
+ TBEs[address].ResponseType := CoherenceResponseType:NULL;
+ }
+ }
+
+ action(vd_allocateDmaRequestInTBE, "vd", desc="Record Data in TBE") {
+ peek(dmaRequestQueue_in, DMARequestMsg) {
+ TBEs.allocate(address);
+ TBEs[address].DmaDataBlk := in_msg.DataBlk;
+ TBEs[address].PhysicalAddress := in_msg.PhysicalAddress;
+ TBEs[address].Len := in_msg.Len;
+ TBEs[address].DmaRequestor := in_msg.Requestor;
+ TBEs[address].ResponseType := CoherenceResponseType:DATA_EXCLUSIVE;
+ //
+ // One ack for each last-level cache
+ //
+ TBEs[address].NumPendingMsgs := getNumberOfLastLevelCaches();
+ //
+ // Assume initially that the caches store a clean copy and that memory
+ // will provide the data
+ //
+ TBEs[address].CacheDirty := false;
+ }
+ }
+
+ action(w_deallocateTBE, "w", desc="Deallocate TBE") {
+ TBEs.deallocate(address);
+ }
+
+ action(m_decrementNumberOfMessages, "m", desc="Decrement the number of messages for which we're waiting") {
+ peek(responseToDir_in, ResponseMsg) {
+ assert(in_msg.Acks > 0);
+ DEBUG_EXPR(TBEs[address].NumPendingMsgs);
+ //
+ // Note that cache data responses will have an ack count of 2. However,
+ // directory DMA requests must wait for acks from all LLC caches, so
+ // only decrement by 1.
+ //
+ TBEs[address].NumPendingMsgs := TBEs[address].NumPendingMsgs - 1;
+ DEBUG_EXPR(TBEs[address].NumPendingMsgs);
+ }
+ }
+
+ action(n_popResponseQueue, "n", desc="Pop response queue") {
+ responseToDir_in.dequeue();
+ }
+
+ action(o_checkForCompletion, "o", desc="Check if we have received all the messages required for completion") {
+ if (TBEs[address].NumPendingMsgs == 0) {
+ enqueue(triggerQueue_out, TriggerMsg) {
+ out_msg.Address := address;
+ if (TBEs[address].Sharers) {
+ out_msg.Type := TriggerType:ALL_ACKS;
+ } else {
+ out_msg.Type := TriggerType:ALL_ACKS_NO_SHARERS;
+ }
+ }
+ }
+ }
+
+ action(d_sendData, "d", desc="Send data to requestor") {
+ peek(memQueue_in, MemoryMsg) {
+ enqueue(responseNetwork_out, ResponseMsg, latency="1") {
+ out_msg.Address := address;
+ out_msg.Type := TBEs[address].ResponseType;
+ out_msg.Sender := machineID;
+ out_msg.Destination.add(in_msg.OriginalRequestorMachId);
+ out_msg.DataBlk := in_msg.DataBlk;
+ out_msg.Dirty := false; // By definition, the block is now clean
+ out_msg.Acks := 1;
+ out_msg.MessageSize := MessageSizeType:Response_Data;
+ }
+ }
+ }
+
+ action(dr_sendDmaData, "dr", desc="Send Data to DMA controller from memory") {
+ peek(memQueue_in, MemoryMsg) {
+ enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") {
+ out_msg.PhysicalAddress := address;
+ out_msg.LineAddress := address;
+ out_msg.Type := DMAResponseType:DATA;
+ //
+ // we send the entire data block and rely on the dma controller to
+ // split it up if need be
+ //
+ out_msg.DataBlk := in_msg.DataBlk;
+ out_msg.Destination.add(TBEs[address].DmaRequestor);
+ out_msg.MessageSize := MessageSizeType:Response_Data;
+ }
+ }
+ }
+
+ action(dt_sendDmaDataFromTbe, "dt", desc="Send Data to DMA controller from tbe") {
+ peek(triggerQueue_in, TriggerMsg) {
+ enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") {
+ out_msg.PhysicalAddress := address;
+ out_msg.LineAddress := address;
+ out_msg.Type := DMAResponseType:DATA;
+ //
+ // we send the entire data block and rely on the dma controller to
+ // split it up if need be
+ //
+ out_msg.DataBlk := TBEs[address].DataBlk;
+ out_msg.Destination.add(TBEs[address].DmaRequestor);
+ out_msg.MessageSize := MessageSizeType:Response_Data;
+ }
+ }
+ }
+
+ action(da_sendDmaAck, "da", desc="Send Ack to DMA controller") {
+ enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") {
+ out_msg.PhysicalAddress := address;
+ out_msg.LineAddress := address;
+ out_msg.Type := DMAResponseType:ACK;
+ out_msg.Destination.add(TBEs[address].DmaRequestor);
+ out_msg.MessageSize := MessageSizeType:Writeback_Control;
+ }
+ }
+
+ action(rx_recordExclusiveInTBE, "rx", desc="Record Exclusive in TBE") {
+ peek(requestQueue_in, RequestMsg) {
+ TBEs[address].ResponseType := CoherenceResponseType:DATA_EXCLUSIVE;
+ }
+ }
+
+ action(r_recordDataInTBE, "rt", desc="Record Data in TBE") {
+ peek(requestQueue_in, RequestMsg) {
+ TBEs[address].ResponseType := CoherenceResponseType:DATA;
+ }
+ }
+
+ action(r_setSharerBit, "r", desc="We saw other sharers") {
+ TBEs[address].Sharers := true;
+ }
+
+ action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
+ peek(requestQueue_in, RequestMsg) {
+ enqueue(memQueue_out, MemoryMsg, latency="1") {
+ out_msg.Address := address;
+ out_msg.Type := MemoryRequestType:MEMORY_READ;
+ out_msg.Sender := machineID;
+ out_msg.OriginalRequestorMachId := in_msg.Requestor;
+ out_msg.MessageSize := in_msg.MessageSize;
+ out_msg.DataBlk := directory[address].DataBlk;
+ DEBUG_EXPR(out_msg);
+ }
+ }
+ }
+
+ action(qd_queueMemoryRequestFromDmaRead, "qd", desc="Queue off-chip fetch request") {
+ peek(dmaRequestQueue_in, DMARequestMsg) {
+ enqueue(memQueue_out, MemoryMsg, latency="1") {
+ out_msg.Address := address;
+ out_msg.Type := MemoryRequestType:MEMORY_READ;
+ out_msg.Sender := machineID;
+ out_msg.OriginalRequestorMachId := in_msg.Requestor;
+ out_msg.MessageSize := in_msg.MessageSize;
+ out_msg.DataBlk := directory[address].DataBlk;
+ DEBUG_EXPR(out_msg);
+ }
+ }
+ }
+
+ action(f_forwardRequest, "f", desc="Forward requests") {
+ if (getNumberOfLastLevelCaches() > 1) {
+ peek(requestQueue_in, RequestMsg) {
+ enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) {
+ out_msg.Address := address;
+ out_msg.Type := in_msg.Type;
+ out_msg.Requestor := in_msg.Requestor;
+ out_msg.Destination.broadcast(MachineType:L1Cache); // Send to all L1 caches
+ out_msg.Destination.remove(in_msg.Requestor); // Don't include the original requestor
+ out_msg.MessageSize := MessageSizeType:Forwarded_Control;
+ }
+ }
+ }
+ }
+
+ action(f_forwardWriteFromDma, "fw", desc="Forward requests") {
+ peek(dmaRequestQueue_in, DMARequestMsg) {
+ enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) {
+ out_msg.Address := address;
+ out_msg.Type := CoherenceRequestType:GETX;
+ //
+ // Send to all L1 caches, since the requestor is the memory controller
+ // itself
+ //
+ out_msg.Requestor := machineID;
+ out_msg.Destination.broadcast(MachineType:L1Cache);
+ out_msg.MessageSize := MessageSizeType:Forwarded_Control;
+ }
+ }
+ }
+
+ action(f_forwardReadFromDma, "fr", desc="Forward requests") {
+ peek(dmaRequestQueue_in, DMARequestMsg) {
+ enqueue(forwardNetwork_out, RequestMsg, latency=memory_controller_latency) {
+ out_msg.Address := address;
+ out_msg.Type := CoherenceRequestType:GETS;
+ //
+ // Send to all L1 caches, since the requestor is the memory controller
+ // itself
+ //
+ out_msg.Requestor := machineID;
+ out_msg.Destination.broadcast(MachineType:L1Cache);
+ out_msg.MessageSize := MessageSizeType:Forwarded_Control;
+ }
+ }
+ }
+
+ action(i_popIncomingRequestQueue, "i", desc="Pop incoming request queue") {
+ requestQueue_in.dequeue();
+ }
+
+ action(j_popIncomingUnblockQueue, "j", desc="Pop incoming unblock queue") {
+ unblockNetwork_in.dequeue();
+ }
+
+ action(l_popMemQueue, "q", desc="Pop off-chip request queue") {
+ memQueue_in.dequeue();
+ }
+
+ action(g_popTriggerQueue, "g", desc="Pop trigger queue") {
+ triggerQueue_in.dequeue();
+ }
+
+ action(p_popDmaRequestQueue, "pd", desc="pop dma request queue") {
+ dmaRequestQueue_in.dequeue();
+ }
+
+ action(y_recycleDmaRequestQueue, "y", desc="recycle dma request queue") {
+ dmaRequestQueue_in.recycle();
+ }
+
+ action(r_recordMemoryData, "rd", desc="record data from memory to TBE") {
+ peek(memQueue_in, MemoryMsg) {
+ if (TBEs[address].CacheDirty == false) {
+ TBEs[address].DataBlk := in_msg.DataBlk;
+ }
+ }
+ }
+
+ action(r_recordCacheData, "rc", desc="record data from cache response to TBE") {
+ peek(responseToDir_in, ResponseMsg) {
+ TBEs[address].CacheDirty := true;
+ TBEs[address].DataBlk := in_msg.DataBlk;
+ }
+ }
+
+ action(l_writeDataToMemory, "l", desc="Write PUTX/PUTO data to memory") {
+ peek(unblockNetwork_in, ResponseMsg) {
+ assert(in_msg.Dirty);
+ assert(in_msg.MessageSize == MessageSizeType:Writeback_Data);
+ directory[address].DataBlk := in_msg.DataBlk;
+ DEBUG_EXPR(in_msg.Address);
+ DEBUG_EXPR(in_msg.DataBlk);
+ }
+ }
+
+ action(dwt_writeDmaDataFromTBE, "dwt", desc="DMA Write data to memory from TBE") {
+ directory[address].DataBlk := TBEs[address].DataBlk;
+ directory[address].DataBlk.copyPartial(TBEs[address].DmaDataBlk, addressOffset(TBEs[address].PhysicalAddress), TBEs[address].Len);
+ }
+
+ action(a_assertCacheData, "ac", desc="Assert that a cache provided the data") {
+ assert(TBEs[address].CacheDirty);
+ }
+
+ action(l_queueMemoryWBRequest, "lq", desc="Write PUTX data to memory") {
+ peek(unblockNetwork_in, ResponseMsg) {
+ enqueue(memQueue_out, MemoryMsg, latency="1") {
+ out_msg.Address := address;
+ out_msg.Type := MemoryRequestType:MEMORY_WB;
+ DEBUG_EXPR(out_msg);
+ }
+ }
+ }
+
+ action(ld_queueMemoryDmaWrite, "ld", desc="Write DMA data to memory") {
+ enqueue(memQueue_out, MemoryMsg, latency="1") {
+ out_msg.Address := address;
+ out_msg.Type := MemoryRequestType:MEMORY_WB;
+ // first, initialize the data blk to the current version of system memory
+ out_msg.DataBlk := TBEs[address].DataBlk;
+ // then add the dma write data
+ out_msg.DataBlk.copyPartial(TBEs[address].DmaDataBlk, addressOffset(TBEs[address].PhysicalAddress), TBEs[address].Len);
+ DEBUG_EXPR(out_msg);
+ }
+ }
+
+ action(ll_checkIncomingWriteback, "\l", desc="Check PUTX/PUTO response message") {
+ peek(unblockNetwork_in, ResponseMsg) {
+ assert(in_msg.Dirty == false);
+ assert(in_msg.MessageSize == MessageSizeType:Writeback_Control);
+
+ // NOTE: The following check would not be valid in a real
+ // implementation. We include the data in the "dataless"
+ // message so we can assert the clean data matches the datablock
+ // in memory
+ assert(directory[address].DataBlk == in_msg.DataBlk);
+ }
+ }
+
+ action(zz_recycleRequest, "\z", desc="Recycle the request queue") {
+ requestQueue_in.recycle();
+ }
+
+ // TRANSITIONS
+
+ // Transitions out of E state
+ transition(E, GETX, NO_B_W) {
+ v_allocateTBE;
+ rx_recordExclusiveInTBE;
+ qf_queueMemoryFetchRequest;
+ f_forwardRequest;
+ i_popIncomingRequestQueue;
+ }
+
+ transition(E, GETS, NO_B_W) {
+ v_allocateTBE;
+ rx_recordExclusiveInTBE;
+ qf_queueMemoryFetchRequest;
+ f_forwardRequest;
+ i_popIncomingRequestQueue;
+ }
+
+ transition(E, DMA_READ, NO_DR_B_W) {
+ vd_allocateDmaRequestInTBE;
+ qd_queueMemoryRequestFromDmaRead;
+ f_forwardReadFromDma;
+ p_popDmaRequestQueue;
+ }
+
+ // Transitions out of O state
+ transition(O, GETX, NO_B_W) {
+ v_allocateTBE;
+ r_recordDataInTBE;
+ qf_queueMemoryFetchRequest;
+ f_forwardRequest;
+ i_popIncomingRequestQueue;
+ }
+
+ transition(O, GETS, O_B_W) {
+ v_allocateTBE;
+ r_recordDataInTBE;
+ qf_queueMemoryFetchRequest;
+ f_forwardRequest;
+ i_popIncomingRequestQueue;
+ }
+
+ transition(O, DMA_READ, O_DR_B_W) {
+ vd_allocateDmaRequestInTBE;
+ qd_queueMemoryRequestFromDmaRead;
+ f_forwardReadFromDma;
+ p_popDmaRequestQueue;
+ }
+
+ transition({E, O, NO}, DMA_WRITE, NO_DW_B_W) {
+ vd_allocateDmaRequestInTBE;
+ f_forwardWriteFromDma;
+ p_popDmaRequestQueue;
+ }
+
+ // Transitions out of NO state
+ transition(NO, GETX, NO_B) {
+ f_forwardRequest;
+ i_popIncomingRequestQueue;
+ }
+
+ transition(NO, GETS, NO_B) {
+ f_forwardRequest;
+ i_popIncomingRequestQueue;
+ }
+
+ transition(NO, PUT, WB) {
+ a_sendWriteBackAck;
+ i_popIncomingRequestQueue;
+ }
+
+ transition(NO, DMA_READ, NO_DR_B_D) {
+ vd_allocateDmaRequestInTBE;
+ f_forwardReadFromDma;
+ p_popDmaRequestQueue;
+ }
+
+ // Nack PUT requests when races cause us to believe we own the data
+ transition({O, E}, PUT) {
+ b_sendWriteBackNack;
+ i_popIncomingRequestQueue;
+ }
+
+ // Blocked transient states
+ transition({NO_B, O_B, NO_DR_B_W, NO_DW_B_W, NO_B_W, NO_DR_B_D,
+ NO_DR_B, O_DR_B, O_B_W, O_DR_B_W, NO_DW_W,
+ NO_W, O_W, WB, WB_E_W, WB_O_W},
+ {GETS, GETX, PUT}) {
+ zz_recycleRequest;
+ }
+
+ transition({NO_B, O_B, NO_DR_B_W, NO_DW_B_W, NO_B_W, NO_DR_B_D,
+ NO_DR_B, O_DR_B, O_B_W, O_DR_B_W, NO_DW_W,
+ NO_W, O_W, WB, WB_E_W, WB_O_W},
+ {DMA_READ, DMA_WRITE}) {
+ y_recycleDmaRequestQueue;
+ }
+
+ transition(NO_B, Unblock, NO) {
+ j_popIncomingUnblockQueue;
+ }
+
+ transition(O_B, Unblock, O) {
+ j_popIncomingUnblockQueue;
+ }
+
+ transition(NO_B_W, Memory_Data, NO_B) {
+ d_sendData;
+ w_deallocateTBE;
+ l_popMemQueue;
+ }
+
+ transition(NO_DR_B_W, Memory_Data, NO_DR_B) {
+ r_recordMemoryData;
+ o_checkForCompletion;
+ l_popMemQueue;
+ }
+
+ transition(O_DR_B_W, Memory_Data, O_DR_B) {
+ r_recordMemoryData;
+ dr_sendDmaData;
+ o_checkForCompletion;
+ l_popMemQueue;
+ }
+
+ transition({NO_DR_B, O_DR_B, NO_DR_B_D, NO_DW_B_W}, Ack) {
+ m_decrementNumberOfMessages;
+ o_checkForCompletion;
+ n_popResponseQueue;
+ }
+
+ transition(NO_DR_B_W, Ack) {
+ m_decrementNumberOfMessages;
+ n_popResponseQueue;
+ }
+
+ transition(NO_DR_B_W, Shared_Ack) {
+ m_decrementNumberOfMessages;
+ r_setSharerBit;
+ n_popResponseQueue;
+ }
+
+ transition({NO_DR_B, NO_DR_B_D}, Shared_Ack) {
+ m_decrementNumberOfMessages;
+ r_setSharerBit;
+ o_checkForCompletion;
+ n_popResponseQueue;
+ }
+
+ transition(NO_DR_B_W, Shared_Data) {
+ r_recordCacheData;
+ m_decrementNumberOfMessages;
+ r_setSharerBit;
+ o_checkForCompletion;
+ n_popResponseQueue;
+ }
+
+ transition({NO_DR_B, NO_DR_B_D}, Shared_Data) {
+ r_recordCacheData;
+ m_decrementNumberOfMessages;
+ r_setSharerBit;
+ o_checkForCompletion;
+ n_popResponseQueue;
+ }
+
+ transition(NO_DR_B_W, Exclusive_Data) {
+ r_recordCacheData;
+ m_decrementNumberOfMessages;
+ n_popResponseQueue;
+ }
+
+ transition({NO_DR_B, NO_DR_B_D, NO_DW_B_W}, Exclusive_Data) {
+ r_recordCacheData;
+ m_decrementNumberOfMessages;
+ o_checkForCompletion;
+ n_popResponseQueue;
+ }
+
+ transition(NO_DR_B, All_acks_and_data, O) {
+ //
+ // Note that the DMA consistency model allows us to send the DMA device
+ // a response as soon as we receive valid data and prior to receiving
+ // all acks. However, to simplify the protocol we wait for all acks.
+ //
+ dt_sendDmaDataFromTbe;
+ w_deallocateTBE;
+ g_popTriggerQueue;
+ }
+
+ transition(NO_DR_B_D, All_acks_and_data, O) {
+ //
+ // Note that the DMA consistency model allows us to send the DMA device
+ // a response as soon as we receive valid data and prior to receiving
+ // all acks. However, to simplify the protocol we wait for all acks.
+ //
+ dt_sendDmaDataFromTbe;
+ w_deallocateTBE;
+ g_popTriggerQueue;
+ }
+
+ transition(O_DR_B, All_acks_and_data_no_sharers, O) {
+ w_deallocateTBE;
+ g_popTriggerQueue;
+ }
+
+ transition(NO_DR_B, All_acks_and_data_no_sharers, E) {
+ //
+ // Note that the DMA consistency model allows us to send the DMA device
+ // a response as soon as we receive valid data and prior to receiving
+ // all acks. However, to simplify the protocol we wait for all acks.
+ //
+ dt_sendDmaDataFromTbe;
+ w_deallocateTBE;
+ g_popTriggerQueue;
+ }
+
+ transition(NO_DR_B_D, All_acks_and_data_no_sharers, E) {
+ a_assertCacheData;
+ //
+ // Note that the DMA consistency model allows us to send the DMA device
+ // a response as soon as we receive valid data and prior to receiving
+ // all acks. However, to simplify the protocol we wait for all acks.
+ //
+ dt_sendDmaDataFromTbe;
+ w_deallocateTBE;
+ g_popTriggerQueue;
+ }
+
+ transition(NO_DW_B_W, All_acks_and_data_no_sharers, NO_DW_W) {
+ dwt_writeDmaDataFromTBE;
+ ld_queueMemoryDmaWrite;
+ g_popTriggerQueue;
+ }
+
+ transition(NO_DW_W, Memory_Ack, E) {
+ da_sendDmaAck;
+ w_deallocateTBE;
+ l_popMemQueue;
+ }
+
+ transition(O_B_W, Memory_Data, O_B) {
+ d_sendData;
+ w_deallocateTBE;
+ l_popMemQueue;
+ }
+
+ transition(NO_B_W, Unblock, NO_W) {
+ j_popIncomingUnblockQueue;
+ }
+
+ transition(O_B_W, Unblock, O_W) {
+ j_popIncomingUnblockQueue;
+ }
+
+ transition(NO_W, Memory_Data, NO) {
+ w_deallocateTBE;
+ l_popMemQueue;
+ }
+
+ transition(O_W, Memory_Data, O) {
+ w_deallocateTBE;
+ l_popMemQueue;
+ }
+
+ // WB State Transistions
+ transition(WB, Writeback_Dirty, WB_E_W) {
+ l_writeDataToMemory;
+ l_queueMemoryWBRequest;
+ j_popIncomingUnblockQueue;
+ }
+
+ transition(WB, Writeback_Exclusive_Dirty, WB_O_W) {
+ l_writeDataToMemory;
+ l_queueMemoryWBRequest;
+ j_popIncomingUnblockQueue;
+ }
+
+ transition(WB_E_W, Memory_Ack, E) {
+ l_popMemQueue;
+ }
+
+ transition(WB_O_W, Memory_Ack, O) {
+ l_popMemQueue;
+ }
+
+ transition(WB, Writeback_Clean, O) {
+ ll_checkIncomingWriteback;
+ j_popIncomingUnblockQueue;
+ }
+
+ transition(WB, Writeback_Exclusive_Clean, E) {
+ ll_checkIncomingWriteback;
+ j_popIncomingUnblockQueue;
+ }
+
+ transition(WB, Unblock, NO) {
+ j_popIncomingUnblockQueue;
+ }
+}
diff --git a/src/mem/protocol/MOESI_hammer-dma.sm b/src/mem/protocol/MOESI_hammer-dma.sm
new file mode 100644
index 000000000..b217923a4
--- /dev/null
+++ b/src/mem/protocol/MOESI_hammer-dma.sm
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+machine(DMA, "DMA Controller")
+: int request_latency
+{
+
+ MessageBuffer responseFromDir, network="From", virtual_network="4", ordered="true", no_vector="true";
+ MessageBuffer reqToDirectory, network="To", virtual_network="5", ordered="false", no_vector="true";
+
+ enumeration(State, desc="DMA states", default="DMA_State_READY") {
+ READY, desc="Ready to accept a new request";
+ BUSY_RD, desc="Busy: currently processing a request";
+ BUSY_WR, desc="Busy: currently processing a request";
+ }
+
+ enumeration(Event, desc="DMA events") {
+ ReadRequest, desc="A new read request";
+ WriteRequest, desc="A new write request";
+ Data, desc="Data from a DMA memory read";
+ Ack, desc="DMA write to memory completed";
+ }
+
+ external_type(DMASequencer) {
+ void ackCallback();
+ void dataCallback(DataBlock);
+ }
+
+ MessageBuffer mandatoryQueue, ordered="false", no_vector="true";
+ DMASequencer dma_sequencer, factory='RubySystem::getDMASequencer(m_cfg["dma_sequencer"])', no_vector="true";
+ State cur_state, no_vector="true";
+
+ State getState(Address addr) {
+ return cur_state;
+ }
+ void setState(Address addr, State state) {
+ cur_state := state;
+ }
+
+ out_port(reqToDirectory_out, DMARequestMsg, reqToDirectory, desc="...");
+
+ in_port(dmaRequestQueue_in, SequencerMsg, mandatoryQueue, desc="...") {
+ if (dmaRequestQueue_in.isReady()) {
+ peek(dmaRequestQueue_in, SequencerMsg) {
+ if (in_msg.Type == SequencerRequestType:LD ) {
+ trigger(Event:ReadRequest, in_msg.LineAddress);
+ } else if (in_msg.Type == SequencerRequestType:ST) {
+ trigger(Event:WriteRequest, in_msg.LineAddress);
+ } else {
+ error("Invalid request type");
+ }
+ }
+ }
+ }
+
+ in_port(dmaResponseQueue_in, DMAResponseMsg, responseFromDir, desc="...") {
+ if (dmaResponseQueue_in.isReady()) {
+ peek( dmaResponseQueue_in, DMAResponseMsg) {
+ if (in_msg.Type == DMAResponseType:ACK) {
+ trigger(Event:Ack, in_msg.LineAddress);
+ } else if (in_msg.Type == DMAResponseType:DATA) {
+ trigger(Event:Data, in_msg.LineAddress);
+ } else {
+ error("Invalid response type");
+ }
+ }
+ }
+ }
+
+ action(s_sendReadRequest, "s", desc="Send a DMA read request to memory") {
+ peek(dmaRequestQueue_in, SequencerMsg) {
+ enqueue(reqToDirectory_out, DMARequestMsg, latency=request_latency) {
+ out_msg.PhysicalAddress := in_msg.PhysicalAddress;
+ out_msg.LineAddress := in_msg.LineAddress;
+ out_msg.Type := DMARequestType:READ;
+ out_msg.Requestor := machineID;
+ out_msg.DataBlk := in_msg.DataBlk;
+ out_msg.Len := in_msg.Len;
+ out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.MessageSize := MessageSizeType:Writeback_Control;
+ }
+ }
+ }
+
+ action(s_sendWriteRequest, "\s", desc="Send a DMA write request to memory") {
+ peek(dmaRequestQueue_in, SequencerMsg) {
+ enqueue(reqToDirectory_out, DMARequestMsg, latency=request_latency) {
+ out_msg.PhysicalAddress := in_msg.PhysicalAddress;
+ out_msg.LineAddress := in_msg.LineAddress;
+ out_msg.Type := DMARequestType:WRITE;
+ out_msg.Requestor := machineID;
+ out_msg.DataBlk := in_msg.DataBlk;
+ out_msg.Len := in_msg.Len;
+ out_msg.Destination.add(map_Address_to_Directory(address));
+ out_msg.MessageSize := MessageSizeType:Writeback_Control;
+ }
+ }
+ }
+
+ action(a_ackCallback, "a", desc="Notify dma controller that write request completed") {
+ peek (dmaResponseQueue_in, DMAResponseMsg) {
+ dma_sequencer.ackCallback();
+ }
+ }
+
+ action(d_dataCallback, "d", desc="Write data to dma sequencer") {
+ peek (dmaResponseQueue_in, DMAResponseMsg) {
+ dma_sequencer.dataCallback(in_msg.DataBlk);
+ }
+ }
+
+ action(p_popRequestQueue, "p", desc="Pop request queue") {
+ dmaRequestQueue_in.dequeue();
+ }
+
+ action(p_popResponseQueue, "\p", desc="Pop request queue") {
+ dmaResponseQueue_in.dequeue();
+ }
+
+ transition(READY, ReadRequest, BUSY_RD) {
+ s_sendReadRequest;
+ p_popRequestQueue;
+ }
+
+ transition(READY, WriteRequest, BUSY_WR) {
+ s_sendWriteRequest;
+ p_popRequestQueue;
+ }
+
+ transition(BUSY_RD, Data, READY) {
+ d_dataCallback;
+ p_popResponseQueue;
+ }
+
+ transition(BUSY_WR, Ack, READY) {
+ a_ackCallback;
+ p_popResponseQueue;
+ }
+}
diff --git a/src/mem/protocol/MOESI_hammer-msg.sm b/src/mem/protocol/MOESI_hammer-msg.sm
new file mode 100644
index 000000000..5d8226eb6
--- /dev/null
+++ b/src/mem/protocol/MOESI_hammer-msg.sm
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * AMD's contributions to the MOESI hammer protocol do not constitute an
+ * endorsement of its similarity to any AMD products.
+ */
+
+// CoherenceRequestType
+enumeration(CoherenceRequestType, desc="...") {
+ GETX, desc="Get eXclusive";
+ GETS, desc="Get Shared";
+ PUT, desc="Put Ownership";
+ WB_ACK, desc="Writeback ack";
+ WB_NACK, desc="Writeback neg. ack";
+}
+
+// CoherenceResponseType
+enumeration(CoherenceResponseType, desc="...") {
+ ACK, desc="ACKnowledgment, responder does not have a copy";
+ ACK_SHARED, desc="ACKnowledgment, responder has a shared copy";
+ DATA, desc="Data, responder does not have a copy";
+ DATA_SHARED, desc="Data, responder has a shared copy";
+ DATA_EXCLUSIVE, desc="Data, responder was exclusive, gave us a copy, and they went to invalid";
+ WB_CLEAN, desc="Clean writeback";
+ WB_DIRTY, desc="Dirty writeback";
+ WB_EXCLUSIVE_CLEAN, desc="Clean writeback of exclusive data";
+ WB_EXCLUSIVE_DIRTY, desc="Dirty writeback of exclusive data";
+ UNBLOCK, desc="Unblock";
+ NULL, desc="Null value";
+}
+
+// TriggerType
+enumeration(TriggerType, desc="...") {
+ ALL_ACKS, desc="See corresponding event";
+ ALL_ACKS_NO_SHARERS, desc="See corresponding event";
+}
+
+// TriggerMsg
+structure(TriggerMsg, desc="...", interface="Message") {
+ Address Address, desc="Physical address for this request";
+ TriggerType Type, desc="Type of trigger";
+}
+
+// RequestMsg (and also forwarded requests)
+structure(RequestMsg, desc="...", interface="NetworkMessage") {
+ Address Address, desc="Physical address for this request";
+ CoherenceRequestType Type, desc="Type of request (GetS, GetX, PutX, etc)";
+ MachineID Requestor, desc="Node who initiated the request";
+ NetDest Destination, desc="Multicast destination mask";
+ MessageSizeType MessageSize, desc="size category of the message";
+}
+
+// ResponseMsg (and also unblock requests)
+structure(ResponseMsg, desc="...", interface="NetworkMessage") {
+ Address Address, desc="Physical address for this request";
+ CoherenceResponseType Type, desc="Type of response (Ack, Data, etc)";
+ MachineID Sender, desc="Node who sent the data";
+ NetDest Destination, desc="Node to whom the data is sent";
+ DataBlock DataBlk, desc="data for the cache line";
+ bool Dirty, desc="Is the data dirty (different than memory)?";
+ int Acks, desc="How many messages this counts as";
+ MessageSizeType MessageSize, desc="size category of the message";
+}
+
+enumeration(DMARequestType, desc="...", default="DMARequestType_NULL") {
+ READ, desc="Memory Read";
+ WRITE, desc="Memory Write";
+ NULL, desc="Invalid";
+}
+
+enumeration(DMAResponseType, desc="...", default="DMAResponseType_NULL") {
+ DATA, desc="DATA read";
+ ACK, desc="ACK write";
+ NULL, desc="Invalid";
+}
+
+structure(DMARequestMsg, desc="...", interface="NetworkMessage") {
+ DMARequestType Type, desc="Request type (read/write)";
+ Address PhysicalAddress, desc="Physical address for this request";
+ Address LineAddress, desc="Line address for this request";
+ MachineID Requestor, desc="Node who initiated the request";
+ NetDest Destination, desc="Destination";
+ DataBlock DataBlk, desc="DataBlk attached to this request";
+ int Len, desc="The length of the request";
+ MessageSizeType MessageSize, desc="size category of the message";
+}
+
+structure(DMAResponseMsg, desc="...", interface="NetworkMessage") {
+ DMAResponseType Type, desc="Response type (DATA/ACK)";
+ Address PhysicalAddress, desc="Physical address for this request";
+ Address LineAddress, desc="Line address for this request";
+ NetDest Destination, desc="Destination";
+ DataBlock DataBlk, desc="DataBlk attached to this request";
+ MessageSizeType MessageSize, desc="size category of the message";
+}
diff --git a/src/mem/protocol/MOESI_hammer.slicc b/src/mem/protocol/MOESI_hammer.slicc
new file mode 100644
index 000000000..31ad47c2e
--- /dev/null
+++ b/src/mem/protocol/MOESI_hammer.slicc
@@ -0,0 +1,5 @@
+MOESI_hammer-msg.sm
+MOESI_hammer-cache.sm
+MOESI_hammer-dir.sm
+MOESI_hammer-dma.sm
+standard_1level_CMP-protocol.sm
diff --git a/src/mem/protocol/RubySlicc_ComponentMapping.sm b/src/mem/protocol/RubySlicc_ComponentMapping.sm
index 0da1a05e2..891820c46 100644
--- a/src/mem/protocol/RubySlicc_ComponentMapping.sm
+++ b/src/mem/protocol/RubySlicc_ComponentMapping.sm
@@ -29,6 +29,8 @@
// Mapping functions
+int getNumberOfLastLevelCaches();
+
// NodeID map_address_to_node(Address addr);
MachineID mapAddressToRange(Address addr, MachineType type, int low, int high);
NetDest broadcast(MachineType type);
diff --git a/src/mem/protocol/RubySlicc_Util.sm b/src/mem/protocol/RubySlicc_Util.sm
index 312682bd7..e1771448f 100644
--- a/src/mem/protocol/RubySlicc_Util.sm
+++ b/src/mem/protocol/RubySlicc_Util.sm
@@ -52,7 +52,6 @@ void dirProfileCoherenceRequest(NodeID node, bool needCLB);
bool isPerfectProtocol();
bool L1trainsPrefetcher();
int max_tokens();
-int N_tokens();
bool distributedPersistentEnabled();
Address setOffset(Address addr, int offset);
Address makeLineAddress(Address addr);
diff --git a/src/mem/protocol/SConscript b/src/mem/protocol/SConscript
index 293346f13..cd9920d22 100644
--- a/src/mem/protocol/SConscript
+++ b/src/mem/protocol/SConscript
@@ -29,30 +29,51 @@
# Authors: Nathan Binkert
import os
-import re
-import string
import sys
-from os.path import basename, dirname, exists, expanduser, isdir, isfile
-from os.path import join as joinpath
-
-import SCons
+from os.path import isdir, isfile, join as joinpath
Import('*')
if not env['RUBY']:
Return()
-slicc_dir = Dir('../slicc')
protocol_dir = Dir('.')
html_dir = Dir('html')
+slicc_dir = Dir('../slicc')
+
+sys.path[1:1] = [ Dir('..').srcnode().abspath ]
+from slicc.parser import SLICC
+
+slicc_depends = []
+for root,dirs,files in os.walk(slicc_dir.srcnode().abspath):
+ for f in files:
+ if f.endswith('.py'):
+ slicc_depends.append(File(joinpath(root, f)))
#
# Use SLICC
#
-def slicc_generator(target, source, env, for_signature):
- slicc_bin = str(source[0])
- protocol = source[1].get_contents()
+
+def slicc_scanner(node, env, path):
+ contents = node.get_contents()
+ files = [ line.strip() for line in contents.splitlines() ]
+ return files
+
+env.Append(SCANNERS=Scanner(function=slicc_scanner,skeys=['.slicc']))
+
+def slicc_emitter(target, source, env):
+ files = [s.srcnode().abspath for s in source[1:]]
+ slicc = SLICC(debug=True)
+ print "SLICC parsing..."
+ for name in slicc.load(files, verbose=True):
+ print " %s" % name
+
+ target.extend(sorted(slicc.files()))
+ return target, source
+
+def slicc_action(target, source, env):
+ protocol = source[0].get_contents()
pdir = str(protocol_dir)
hdir = str(html_dir)
@@ -61,32 +82,31 @@ def slicc_generator(target, source, env, for_signature):
if not isdir(hdir):
os.mkdir(hdir)
- do_html = "html"
- cmdline = [ slicc_bin, pdir, hdir, protocol, do_html ]
- cmdline += [ str(s) for s in source[2:] ]
- cmdline = ' '.join(cmdline)
- return cmdline
+ slicc = SLICC(debug=True)
+ files = [str(s) for s in source[1:]]
+ slicc.load(files, verbose=False)
-slicc_builder = Builder(generator=slicc_generator)
+ print "SLICC Generator pass 1..."
+ slicc.findMachines()
-protocol = env['PROTOCOL']
-sources = [ protocol_dir.File("RubySlicc_interfaces.slicc"),
- protocol_dir.File("%s.slicc" % protocol) ]
+ print "SLICC Generator pass 2..."
+ slicc.generate()
-sys.path[0:0] = [env['ENV']['M5_PLY']]
-execfile(slicc_dir.File('parser/parser.py').srcnode().abspath)
+ print "SLICC writing C++ files..."
+ slicc.writeCodeFiles(pdir)
-sm_files = read_slicc([s.srcnode().abspath for s in sources])
-sm_files = [ protocol_dir.File(f) for f in sm_files ]
+ print "SLICC writing HTML files..."
+ slicc.writeHTMLFiles(hdir)
-hh, cc = scan([s.srcnode().abspath for s in sm_files])
-hh = [ protocol_dir.File(f) for f in hh ]
-cc = [ protocol_dir.File(f) for f in cc ]
+slicc_builder = Builder(action=slicc_action, emitter=slicc_emitter)
-slicc_bin = slicc_dir.File("slicc")
+protocol = env['PROTOCOL']
+sources = [ protocol_dir.File("RubySlicc_interfaces.slicc"),
+ protocol_dir.File("%s.slicc" % protocol) ]
env.Append(BUILDERS={'SLICC' : slicc_builder})
-env.SLICC(hh + cc, [ slicc_bin, Value(protocol) ] + sm_files)
+nodes = env.SLICC([], [ Value(protocol) ] + sources)
+env.Depends(nodes, slicc_depends)
-for f in cc:
+for f in sorted(s for s in nodes if str(s).endswith('.cc')):
Source(f)
diff --git a/src/mem/protocol/SConsopts b/src/mem/protocol/SConsopts
index ded0814d2..10a303681 100644
--- a/src/mem/protocol/SConsopts
+++ b/src/mem/protocol/SConsopts
@@ -47,9 +47,10 @@ all_protocols = [
'MOSI_SMP_bcast_m',
'MOSI_SMP_directory_1level',
'MSI_MOSI_CMP_directory',
+ 'MOESI_hammer',
]
-opt = EnumVariable('PROTOCOL', 'Coherence Protocol for Ruby', 'MI_example',
+opt = EnumVariable('PROTOCOL', 'Coherence Protocol for Ruby', 'MOESI_CMP_directory',
all_protocols)
sticky_vars.AddVariables(opt)
diff --git a/src/mem/request.hh b/src/mem/request.hh
index c8c31ffcd..f2cc4647c 100644
--- a/src/mem/request.hh
+++ b/src/mem/request.hh
@@ -72,8 +72,6 @@ class Request : public FastAlloc
/** This request is to a memory mapped register. */
static const FlagsType MMAPED_IPR = 0x00002000;
- /** The request should not cause a page fault. */
- static const FlagsType NO_FAULT = 0x00010000;
/** The request should ignore unaligned access faults */
static const FlagsType NO_ALIGN_FAULT = 0x00020000;
/** The request should ignore unaligned access faults */
diff --git a/src/mem/ruby/SConscript b/src/mem/ruby/SConscript
index 0c8423c85..3559f042f 100644
--- a/src/mem/ruby/SConscript
+++ b/src/mem/ruby/SConscript
@@ -114,6 +114,7 @@ MakeInclude('system/MachineID.hh')
MakeInclude('system/MemoryControl.hh')
MakeInclude('system/NodeID.hh')
MakeInclude('system/PerfectCacheMemory.hh')
+MakeInclude('system/PersistentTable.hh')
MakeInclude('system/Sequencer.hh')
MakeInclude('system/TBETable.hh')
MakeInclude('system/TimerTable.hh')
diff --git a/src/mem/ruby/buffers/MessageBuffer.cc b/src/mem/ruby/buffers/MessageBuffer.cc
index 3928e94e6..d157e2a94 100644
--- a/src/mem/ruby/buffers/MessageBuffer.cc
+++ b/src/mem/ruby/buffers/MessageBuffer.cc
@@ -34,27 +34,7 @@
#include "mem/ruby/buffers/MessageBuffer.hh"
#include "mem/ruby/system/System.hh"
-MessageBuffer::MessageBuffer()
-{
- m_msg_counter = 0;
- m_consumer_ptr = NULL;
- m_ordering_set = false;
- m_strict_fifo = true;
- m_size = 0;
- m_max_size = -1;
- m_last_arrival_time = 0;
- m_randomization = true;
- m_size_last_time_size_checked = 0;
- m_time_last_time_size_checked = 0;
- m_time_last_time_enqueue = 0;
- m_time_last_time_pop = 0;
- m_size_at_cycle_start = 0;
- m_msgs_this_cycle = 0;
- m_not_avail_count = 0;
- m_priority_rank = 0;
-}
-
-MessageBuffer::MessageBuffer(const Chip* chip_ptr) // The chip_ptr is ignored, but could be used for extra debugging
+MessageBuffer::MessageBuffer(const string &name)
{
m_msg_counter = 0;
m_consumer_ptr = NULL;
@@ -72,6 +52,7 @@ MessageBuffer::MessageBuffer(const Chip* chip_ptr) // The chip_ptr is ignored,
m_msgs_this_cycle = 0;
m_not_avail_count = 0;
m_priority_rank = 0;
+ m_name = name;
}
int MessageBuffer::getSize()
diff --git a/src/mem/ruby/buffers/MessageBuffer.hh b/src/mem/ruby/buffers/MessageBuffer.hh
index 3ca6790d0..8440c3335 100644
--- a/src/mem/ruby/buffers/MessageBuffer.hh
+++ b/src/mem/ruby/buffers/MessageBuffer.hh
@@ -46,15 +46,11 @@
#include "mem/gems_common/PrioHeap.hh"
#include "mem/gems_common/util.hh"
-class Chip;
-
class MessageBuffer {
public:
// Constructors
- MessageBuffer();
- MessageBuffer(const Chip* chip_ptr); // The chip_ptr is ignored, but could be used for extra debugging
+ MessageBuffer(const string &name = "");
- // Use Default Destructor
// ~MessageBuffer()
// Public Methods
diff --git a/src/mem/ruby/common/Address.hh b/src/mem/ruby/common/Address.hh
index c48152354..88cd2668a 100644
--- a/src/mem/ruby/common/Address.hh
+++ b/src/mem/ruby/common/Address.hh
@@ -148,7 +148,7 @@ inline
physical_address_t Address::bitSelect(int small, int big) const // rips bits inclusive
{
physical_address_t mask;
- assert(big >= small);
+ assert((unsigned)big >= (unsigned)small);
if (big >= ADDRESS_WIDTH - 1) {
return (m_address >> small);
diff --git a/src/mem/ruby/common/DataBlock.hh b/src/mem/ruby/common/DataBlock.hh
index 3c8ef56f4..1d399753e 100644
--- a/src/mem/ruby/common/DataBlock.hh
+++ b/src/mem/ruby/common/DataBlock.hh
@@ -45,7 +45,11 @@ class DataBlock {
}
// Destructor
- ~DataBlock() { if(m_alloc) delete [] m_data;}
+ ~DataBlock() {
+ if(m_alloc) {
+ delete [] m_data;
+ }
+ }
DataBlock& operator=(const DataBlock& obj);
diff --git a/src/mem/ruby/common/Debug.cc b/src/mem/ruby/common/Debug.cc
index 1115152f4..cb9fdf082 100644
--- a/src/mem/ruby/common/Debug.cc
+++ b/src/mem/ruby/common/Debug.cc
@@ -39,6 +39,7 @@
#include "mem/ruby/common/Debug.hh"
#include "mem/ruby/eventqueue/RubyEventQueue.hh"
#include "mem/gems_common/util.hh"
+#include "base/misc.hh"
class Debug;
extern Debug* g_debug_ptr;
@@ -70,6 +71,7 @@ DebugComponentData debugComponents[] =
{"Cache", 'c' },
{"Predictor", 'p' },
{"Allocator", 'a' },
+ {"Memory", 'M' },
};
extern "C" void changeDebugVerbosity(VerbosityLevel vb);
@@ -95,19 +97,27 @@ Debug::Debug()
Debug::Debug( const string & name, const vector<string> & argv )
{
- for (size_t i=0;i<argv.size();i+=2){
- if (argv[i] == "filter_string")
- setFilterString( argv[i+1].c_str() );
- else if (argv[i] == "verbosity_string")
+ //
+ // must clear the filter before adding filter strings
+ //
+ clearFilter();
+
+ for (size_t i=0;i<argv.size();i+=2) {
+ if (argv[i] == "filter_string") {
+ if (setFilterString(argv[i+1].c_str())) {
+ fatal("could not set filter string to %s\n", argv[i+1].c_str());
+ }
+ } else if (argv[i] == "verbosity_string") {
setVerbosityString( argv[i+1].c_str() );
- else if (argv[i] == "start_time")
+ } else if (argv[i] == "start_time") {
m_starting_cycle = atoi( argv[i+1].c_str() );
- else if (argv[i] == "output_filename")
+ } else if (argv[i] == "output_filename") {
setDebugOutputFile( argv[i+1].c_str() );
- else if (argv[i] == "protocol_trace")
+ } else if (argv[i] == "protocol_trace") {
m_protocol_trace = string_to_bool(argv[i+1]);
- else
- assert(0);
+ } else {
+ fatal("invalid argument %s\n");
+ }
}
}
@@ -119,7 +129,8 @@ Debug::Debug( const char *filterString, const char *verboseString,
debug_cout_ptr = &cout;
m_starting_cycle = filterStartTime;
- setFilterString( filterString );
+ if (setFilterString(filterString))
+ fatal("could not set filter string to %s\n", filterString);
setVerbosityString( verboseString );
setDebugOutputFile( filename );
}
diff --git a/src/mem/ruby/common/Debug.hh b/src/mem/ruby/common/Debug.hh
index c038d57c2..03e123866 100644
--- a/src/mem/ruby/common/Debug.hh
+++ b/src/mem/ruby/common/Debug.hh
@@ -63,6 +63,7 @@ enum DebugComponents
CACHE_COMP,
PREDICTOR_COMP,
ALLOCATOR_COMP,
+ MEMORY_COMP,
NUMBER_OF_COMPS
};
diff --git a/src/mem/ruby/common/NetDest.cc b/src/mem/ruby/common/NetDest.cc
index 32771235f..35bb4ec43 100644
--- a/src/mem/ruby/common/NetDest.cc
+++ b/src/mem/ruby/common/NetDest.cc
@@ -133,13 +133,14 @@ NodeID NetDest::elementAt(MachineID index) {
return m_bits[vecIndex(index)].elementAt(bitIndex(index.num));
}
-NodeID NetDest::smallestElement() const
+MachineID NetDest::smallestElement() const
{
assert(count() > 0);
for (int i=0; i<m_bits.size(); i++) {
for (int j=0; j<m_bits[i].getSize(); j++) {
if (m_bits[i].isElement(j)) {
- return j;
+ MachineID mach = {MachineType_from_base_level(i), j};
+ return mach;
}
}
}
diff --git a/src/mem/ruby/common/NetDest.hh b/src/mem/ruby/common/NetDest.hh
index 1dcee7b7a..071106623 100644
--- a/src/mem/ruby/common/NetDest.hh
+++ b/src/mem/ruby/common/NetDest.hh
@@ -63,7 +63,7 @@ public:
NetDest& operator=(const Set& obj);
// Destructor
- // ~NetDest();
+ ~NetDest() { DEBUG_MSG(MEMORY_COMP, LowPrio, "NetDest Destructor"); }
// Public Methods
void add(MachineID newElement);
@@ -96,7 +96,7 @@ public:
//For Princeton Network
Vector<NodeID> getAllDest();
- NodeID smallestElement() const;
+ MachineID smallestElement() const;
MachineID smallestElement(MachineType machine) const;
void setSize();
diff --git a/src/mem/ruby/config/MI_example-homogeneous.rb b/src/mem/ruby/config/MI_example-homogeneous.rb
index 409d0fe3a..71e20c318 100644
--- a/src/mem/ruby/config/MI_example-homogeneous.rb
+++ b/src/mem/ruby/config/MI_example-homogeneous.rb
@@ -13,7 +13,7 @@ RubySystem.reset
# default values
num_cores = 2
-l1_cache_size_kb = 32
+l1_cache_size_kb = 32768
l1_cache_assoc = 8
l1_cache_latency = 1
num_memories = 2
@@ -44,6 +44,15 @@ for i in 0..$*.size-1 do
elsif $*[i] == "-s"
memory_size_mb = $*[i+1].to_i
i = i + 1
+ elsif $*[i] == "-C"
+ l1_cache_size_bytes = $*[i+1].to_i
+ i = i + 1
+ elsif $*[i] == "-A"
+ l1_cache_assoc = $*[i+1].to_i
+ i = i + 1
+ elsif $*[i] == "-D"
+ num_dma = $*[i+1].to_i
+ i = i + 1
end
end
@@ -55,7 +64,7 @@ assert(protocol == "MI_example", __FILE__ + " cannot be used with protocol " + p
require protocol+".rb"
num_cores.times { |n|
- cache = SetAssociativeCache.new("l1u_"+n.to_s, l1_cache_size_kb, l1_cache_latency, l1_cache_assoc, "PSEUDO_LRU")
+ cache = SetAssociativeCache.new("l1u_"+n.to_s, l1_cache_size_bytes, l1_cache_latency, l1_cache_assoc, "PSEUDO_LRU")
sequencer = Sequencer.new("Sequencer_"+n.to_s, cache, cache)
iface_ports << sequencer
net_ports << MI_example_CacheController.new("L1CacheController_"+n.to_s,
diff --git a/src/mem/ruby/config/MI_example.rb b/src/mem/ruby/config/MI_example.rb
index 187dc7a68..8113087aa 100644
--- a/src/mem/ruby/config/MI_example.rb
+++ b/src/mem/ruby/config/MI_example.rb
@@ -23,8 +23,6 @@ class MI_example_DirectoryController < DirectoryController
def argv()
vec = super()
vec += " directory_latency "+directory_latency.to_s
- vec += " dma_select_low_bit "+log_int(RubySystem.block_size_bytes).to_s
- vec += " dma_select_num_bits "+log_int(NetPort.totalOfType("DMA")).to_s
end
end
diff --git a/src/mem/ruby/config/MOESI_CMP_token.rb b/src/mem/ruby/config/MOESI_CMP_token.rb
new file mode 100644
index 000000000..ba963dc06
--- /dev/null
+++ b/src/mem/ruby/config/MOESI_CMP_token.rb
@@ -0,0 +1,92 @@
+
+require "cfg.rb"
+require "util.rb"
+
+
+class MOESI_CMP_token_L1CacheController < L1CacheController
+ attr :icache, :dcache
+ attr :num_l2_controllers
+ attr :n_tokens
+ def initialize(obj_name, mach_type, icache, dcache, sequencer, num_l2_controllers, n_tokens)
+ super(obj_name, mach_type, [icache, dcache], sequencer)
+ @icache = icache
+ @dcache = dcache
+ @num_l2_controllers = num_l2_controllers
+ @n_tokens = n_tokens
+ end
+ def argv()
+ num_select_bits = log_int(num_l2_controllers)
+ num_block_bits = log_int(RubySystem.block_size_bytes)
+
+ l2_select_low_bit = num_block_bits
+
+ vec = super()
+ vec += " icache " + @icache.obj_name
+ vec += " dcache " + @dcache.obj_name
+ vec += " l1_request_latency " + l1_request_latency.to_s
+ vec += " l1_response_latency " + l1_response_latency.to_s
+ vec += " l2_select_low_bit " + l2_select_low_bit.to_s
+ vec += " l2_select_num_bits " + num_select_bits.to_s
+ vec += " N_tokens " + n_tokens.to_s
+ vec += " retry_threshold " + retry_threshold.to_s
+ vec += " fixed_timeout_latency " + fixed_timeout_latency.to_s
+ vec += " dynamic_timeout_enabled " + dynamic_timeout_enabled.to_s
+
+ return vec
+ end
+end
+
+class MOESI_CMP_token_L2CacheController < CacheController
+ attr :cache
+ attr :n_tokens
+ def initialize(obj_name, mach_type, cache, n_tokens)
+ super(obj_name, mach_type, [cache])
+ @cache = cache
+ @n_tokens = n_tokens
+ end
+ def argv()
+ vec = super()
+ vec += " cache " + @cache.obj_name
+ vec += " l2_request_latency " + l2_request_latency.to_s
+ vec += " l2_response_latency " + l2_response_latency.to_s
+ vec += " N_tokens " + n_tokens.to_s
+ vec += " filtering_enabled " + filtering_enabled.to_s
+ return vec
+ end
+end
+
+
+class MOESI_CMP_token_DirectoryController < DirectoryController
+ attr :num_l2_controllers
+ def initialize(obj_name, mach_type, directory, memory_control, num_l2_controllers)
+ super(obj_name, mach_type, directory, memory_control)
+ @num_l2_controllers = num_l2_controllers
+ end
+ def argv()
+ num_select_bits = log_int(num_l2_controllers)
+ num_block_bits = log_int(RubySystem.block_size_bytes)
+
+ l2_select_low_bit = num_block_bits
+
+ vec = super()
+ vec += " directory_latency "+directory_latency.to_s
+ vec += " l2_select_low_bit " + l2_select_low_bit.to_s
+ vec += " l2_select_num_bits " + num_select_bits.to_s
+ vec += " distributed_persistent "+distributed_persistent.to_s
+ vec += " fixed_timeout_latency " + fixed_timeout_latency.to_s
+ return vec
+ end
+
+end
+
+class MOESI_CMP_token_DMAController < DMAController
+ def initialize(obj_name, mach_type, dma_sequencer)
+ super(obj_name, mach_type, dma_sequencer)
+ end
+ def argv()
+ vec = super
+ vec += " request_latency "+request_latency.to_s
+ vec += " response_latency "+response_latency.to_s
+ return vec
+ end
+end
diff --git a/src/mem/ruby/config/MOESI_hammer-homogeneous.rb b/src/mem/ruby/config/MOESI_hammer-homogeneous.rb
new file mode 100644
index 000000000..02af0ec27
--- /dev/null
+++ b/src/mem/ruby/config/MOESI_hammer-homogeneous.rb
@@ -0,0 +1,109 @@
+#!/usr/bin/ruby
+#
+# Creates multiple on-chip nodes with three level of cache.
+#
+
+require "cfg.rb"
+
+RubySystem.reset
+
+# default values
+
+num_cores = 2
+l1_cache_size_bytes = 32768
+l1_cache_assoc = 2
+l1_cache_latency = 3
+l2_cache_size_bytes = 1048576
+l2_cache_assoc = 16
+l2_cache_latency = 15
+num_memories = 2
+memory_size_mb = 1024
+num_dma = 0
+use_map = false
+map_levels = 4
+protocol = "MOESI_hammer"
+
+# check for overrides
+
+
+for i in 0..$*.size-1 do
+ if $*[i] == "-c"
+ protocol = $*[i+1]
+ i = i+1
+ elsif $*[i] == "-p"
+ num_cores = $*[i+1].to_i
+ i = i+1
+ elsif $*[i] == "-m"
+ num_memories = $*[i+1].to_i
+ i = i+1
+ elsif $*[i] == "-s"
+ memory_size_mb = $*[i+1].to_i
+ i = i + 1
+ elsif $*[i] == "-U"
+ use_map = $*[i+1]
+ i = i + 1
+ elsif $*[i] == "-C"
+ l1_cache_size_bytes = $*[i+1].to_i
+ i = i + 1
+ elsif $*[i] == "-A"
+ l1_cache_assoc = $*[i+1].to_i
+ i = i + 1
+ elsif $*[i] == "-M"
+ map_levels = $*[i+1].to_i
+ i = i + 1
+ elsif $*[i] == "-D"
+ num_dma = $*[i+1].to_i
+ i = i + 1
+ end
+end
+
+net_ports = Array.new
+iface_ports = Array.new
+
+assert(protocol == "MOESI_hammer", __FILE__ + " cannot be used with protocol " + protocol)
+
+require protocol+".rb"
+
+num_cores.times { |n|
+ icache = SetAssociativeCache.new("l1i_"+n.to_s,
+ l1_cache_size_bytes,
+ l1_cache_latency,
+ l1_cache_assoc,
+ "PSEUDO_LRU")
+ dcache = SetAssociativeCache.new("l1d_"+n.to_s,
+ l1_cache_size_bytes,
+ l1_cache_latency,
+ l1_cache_assoc,
+ "PSEUDO_LRU")
+ l2cache = SetAssociativeCache.new("l2u_"+n.to_s,
+ l2_cache_size_bytes,
+ l2_cache_latency,
+ l2_cache_assoc,
+ "PSEUDO_LRU")
+ sequencer = Sequencer.new("Sequencer_"+n.to_s, icache, dcache)
+ iface_ports << sequencer
+ net_ports << MOESI_hammer_CacheController.new("L1CacheController_"+n.to_s,
+ "L1Cache",
+ icache,
+ dcache,
+ l2cache,
+ sequencer)
+}
+num_memories.times { |n|
+ directory = DirectoryMemory.new("DirectoryMemory_"+n.to_s, memory_size_mb/num_memories)
+ memory_control = MemoryControl.new("MemoryControl_"+n.to_s)
+ net_ports << MOESI_hammer_DirectoryController.new("DirectoryController_"+n.to_s,
+ "Directory",
+ directory,
+ memory_control)
+}
+num_dma.times { |n|
+ dma_sequencer = DMASequencer.new("DMASequencer_"+n.to_s)
+ iface_ports << dma_sequencer
+ net_ports << MOESI_hammer_DMAController.new("DMAController_"+n.to_s, "DMA", dma_sequencer)
+}
+
+topology = CrossbarTopology.new("theTopology", net_ports)
+on_chip_net = Network.new("theNetwork", topology)
+
+RubySystem.init(iface_ports, on_chip_net)
diff --git a/src/mem/ruby/config/MOESI_hammer.rb b/src/mem/ruby/config/MOESI_hammer.rb
new file mode 100644
index 000000000..d3735028b
--- /dev/null
+++ b/src/mem/ruby/config/MOESI_hammer.rb
@@ -0,0 +1,41 @@
+
+require "util.rb"
+
+class MOESI_hammer_CacheController < L1CacheController
+ attr :cache
+ def initialize(obj_name, mach_type, icache, dcache, l2cache, sequencer)
+ super(obj_name, mach_type, [icache, dcache, l2cache], sequencer)
+ @icache = icache
+ @dcache = dcache
+ @l2cache = l2cache
+ end
+ def argv()
+ vec = super()
+ vec += " icache " + @icache.obj_name
+ vec += " dcache " + @dcache.obj_name
+ vec += " l2cache " + @l2cache.obj_name
+ vec += " issue_latency "+issue_latency.to_s
+ vec += " cache_response_latency "+cache_response_latency.to_s
+ end
+
+end
+
+class MOESI_hammer_DirectoryController < DirectoryController
+ def initialize(obj_name, mach_type, directory, memory_control)
+ super(obj_name, mach_type, directory, memory_control)
+ end
+ def argv()
+ vec = super()
+ vec += " memory_controller_latency "+memory_controller_latency.to_s
+ end
+end
+
+class MOESI_hammer_DMAController < DMAController
+ def initialize(obj_name, mach_type, dma_sequencer)
+ super(obj_name, mach_type, dma_sequencer)
+ end
+ def argv()
+ vec = super
+ vec += " request_latency "+request_latency.to_s
+ end
+end
diff --git a/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb b/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb
index a4a1982f4..a8ef1eceb 100644
--- a/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb
+++ b/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb
@@ -27,7 +27,7 @@ memory_size_mb = 1024
num_dma = 1
#default protocol
-protocol = ""#"MESI_CMP_directory"
+protocol = "MOESI_CMP_directory"
# check for overrides
diff --git a/src/mem/ruby/libruby.cc b/src/mem/ruby/libruby.cc
index e4e302eba..b9a72d071 100644
--- a/src/mem/ruby/libruby.cc
+++ b/src/mem/ruby/libruby.cc
@@ -66,6 +66,12 @@ ostream& operator<<(ostream& out, const RubyRequestType& obj)
return out;
}
+ostream& operator<<(std::ostream& out, const RubyRequest& obj)
+{
+ out << hex << "0x" << obj.paddr << flush;
+ return out;
+}
+
vector<string> tokenizeString(string str, string delims)
{
vector<string> tokens;
diff --git a/src/mem/ruby/libruby.hh b/src/mem/ruby/libruby.hh
index 8f1aa8098..4c50611c1 100644
--- a/src/mem/ruby/libruby.hh
+++ b/src/mem/ruby/libruby.hh
@@ -39,6 +39,8 @@ struct RubyRequest {
{}
};
+std::ostream& operator<<(std::ostream& out, const RubyRequest& obj);
+
/**
* Initialize the system. cfg_file is a Ruby-lang configuration script
*/
diff --git a/src/mem/ruby/network/Network.cc b/src/mem/ruby/network/Network.cc
index 984ec7ca8..ac785f632 100644
--- a/src/mem/ruby/network/Network.cc
+++ b/src/mem/ruby/network/Network.cc
@@ -1,3 +1,30 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
#include "mem/protocol/MachineType.hh"
#include "mem/ruby/network/Network.hh"
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh
index 387ed0bc1..c554d7216 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh
@@ -1,9 +1,33 @@
/*
- * CreditLink_d.hh
+ * Copyright (c) 2008 Princeton University
+ * All rights reserved.
*
- * Niket Agarwal, Princeton University
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * */
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Niket Agarwal
+ */
+
#ifndef CREDIT_LINK_D_H
#define CREDIT_LINK_D_H
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc
index 51393b576..df643e800 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * GarnetNetwork_d.cc
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh"
#include "mem/protocol/MachineType.hh"
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh
index f4b809443..997f5e374 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * GarnetNetwork_d.hh
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#ifndef GARNETNETWORK_D_H
#define GARNETNETWORK_D_H
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.cc
index 0ae32de13..7f344b0b7 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.cc
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * InputUnit_d.C
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.hh"
#include "mem/ruby/network/garnet-fixed-pipeline/Router_d.hh"
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.hh
index a59ac89d8..beee79b3e 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.hh
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/InputUnit_d.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * InputUnit_d.hh
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#ifndef INPUT_UNIT_D_H
#define INPUT_UNIT_D_H
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkHeader.hh b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkHeader.hh
index a69dbf107..62ed9a12c 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkHeader.hh
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkHeader.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * NetworkHeader.hh
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#ifndef NETWORK_HEADER_H
#define NETWORK_HEADER_H
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.cc
index 3377ffd1d..c31b76d62 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.cc
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * NetworkInterface_d.cc
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.hh"
#include "mem/ruby/buffers/MessageBuffer.hh"
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.hh
index 625226254..12b8d57e1 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.hh
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * NetworkInterface_d.hh
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#ifndef NET_INTERFACE_D_H
#define NET_INTERFACE_D_H
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.cc
index 8382d331f..dc3c73b0c 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.cc
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * NetworkLink_d.cc
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh"
#include "mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh"
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh
index 90fb9f6dc..fed8afbd3 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * NetworkLink_d.hh
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#ifndef NETWORK_LINK_D_H
#define NETWORK_LINK_D_H
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.cc
index 69e3ae377..42d9af861 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.cc
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * OutVCState_d.cc
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh"
#include "mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh"
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh
index dc64b8504..fe6b5fc79 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * OutVCState_d.hh
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#ifndef OUT_VC_STATE_D_H
#define OUT_VC_STATE_D_H
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.cc
index eb2450897..e672009c9 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.cc
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * OutputUnit_d.cc
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.hh"
#include "mem/ruby/network/garnet-fixed-pipeline/Router_d.hh"
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.hh
index 78f46d1b5..beeab8c7f 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.hh
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * OutputUnit_d.hh
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#ifndef OUTPUT_UNIT_D_H
#define OUTPUT_UNIT_D_H
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.cc
index 161e6ecff..5334de7b9 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.cc
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Router_d.cc
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-fixed-pipeline/Router_d.hh"
#include "mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh"
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.hh
index 23a8681d9..f9af1abfb 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.hh
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,10 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Niket Agarwal
*/
-/*
- * Router_d.hh
- *
- * Niket Agarwal, Princeton University
- *
- * */
#ifndef ROUTER_D_H
#define ROUTER_D_H
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.cc
index 488741055..9f12ac9cc 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.cc
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Routingunit_d.C
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.hh"
#include "mem/ruby/network/garnet-fixed-pipeline/Router_d.hh"
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.hh
index 091ee90ef..33c9f3cc4 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.hh
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/RoutingUnit_d.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Routerunit_d.hh
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#ifndef ROUTING_UNIT_D_H
#define ROUTING_UNIT_D_H
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.cc
index dd0378305..c7308597a 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.cc
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * SWallocator_d.cc
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.hh"
#include "mem/ruby/network/garnet-fixed-pipeline/Router_d.hh"
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.hh
index b1867df7f..f0ec5d77e 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.hh
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * SWallocator_d.hh
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#ifndef SW_ALLOCATOR_D_H
#define SW_ALLOCATOR_D_H
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.cc
index e1ca64864..11a196906 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.cc
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Switch_d.C
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-fixed-pipeline/Switch_d.hh"
#include "mem/ruby/network/garnet-fixed-pipeline/Router_d.hh"
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.hh
index 2e2f524a0..936972714 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.hh
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/Switch_d.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Switch_d.hh
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#ifndef SWITCH_D_H
#define SWITCH_D_H
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.cc
index 810aea175..4150907d1 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.cc
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * VCallocator_d.cc
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh"
#include "mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.hh"
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.hh
index 41e317bff..ad3c2c95f 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.hh
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * VCallocator_d.hh
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#ifndef VC_ALLOCATOR_D_H
#define VC_ALLOCATOR_D_H
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.cc
index 2e4473a29..5ce3ca4e5 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.cc
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * VirtualChannel_d.C
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.hh"
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.hh
index 4ac1898e2..2d81cb7e3 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.hh
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/VirtualChannel_d.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * VirtualChannel_d.hh
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#ifndef VIRTUAL_CHANNEL_D_H
#define VIRTUAL_CHANNEL_D_H
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.cc
index f3ddca0f2..fa189a8cc 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.cc
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * flitBuffer_d.C
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.hh"
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.hh
index 70a47d5f6..2edea9d76 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.hh
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * flitBuffer_d.hh
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#ifndef FLIT_BUFFER_D_H
#define FLIT_BUFFER_D_H
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.cc
index 3defb8029..15e0b0394 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.cc
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * flit_d.C
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-fixed-pipeline/flit_d.hh"
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.hh
index 6f64f4940..39f04052d 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.hh
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/flit_d.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,15 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * flit_d.hh
*
- * Niket Agarwal, Princeton University
- *
- * */
-
+ * Authors: Niket Agarwal
+ */
#ifndef FLIT_D_H
#define FLIT_D_H
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/FlexibleConsumer.hh b/src/mem/ruby/network/garnet-flexible-pipeline/FlexibleConsumer.hh
index f8bf6b949..82179ec21 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/FlexibleConsumer.hh
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/FlexibleConsumer.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,10 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Niket Agarwal
*/
-/*
- * FlexibleConsumer.hh
- *
- * Niket Agarwal, Princeton University
- *
- * */
#ifndef FLEXIBLE_CONSUMER_H
#define FLEXIBLE_CONSUMER_H
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc
index e56f5b5e8..5a6b610f9 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * GarnetNetwork.cc
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh"
#include "mem/protocol/MachineType.hh"
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh
index 194fef778..c0e4ac6e4 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * GarnetNetwork.hh
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#ifndef GARNET_NETWORK_H
#define GARNET_NETWORK_H
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.cc b/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.cc
index cecaf867e..7fdff46b9 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.cc
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * InVCState.C
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-flexible-pipeline/InVcState.hh"
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.hh b/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.hh
index b7005efea..67ff6b459 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.hh
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/InVcState.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,15 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
*
- * InVCState.hh
- *
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#ifndef IN_VC_STATE_H
#define IN_VC_STATE_H
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh
index 0a450c002..2080ef022 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,16 +24,14 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Niket Agarwal
*/
/*
- * NetworkConfig.hh
- *
- * Description: This header file is used to define all configuration parameters required by the interconnection network.
- *
- * Niket Agarwal, Princeton University
- *
- * */
+ * This header file is used to define all configuration parameters
+ * required by the interconnection network.
+ */
#ifndef NETWORKCONFIG_H
#define NETWORKCONFIG_H
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.cc b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.cc
index 597c942b7..4af5b296f 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.cc
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * NetworkInterface.cc
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh"
#include "mem/ruby/buffers/MessageBuffer.hh"
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh
index af4b1d4eb..8444658ea 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,10 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Niket Agarwal
*/
-/*
- * NetworkInterface.hh
- *
- * Niket Agarwal, Princeton University
- *
- * */
#ifndef NET_INTERFACE_H
#define NET_INTERFACE_H
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.cc b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.cc
index ddc92d44c..598c9e2a4 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.cc
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * NetworkLink.cc
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh"
#include "mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh"
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh
index 6cc35b39d..9f5640a2e 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,10 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Niket Agarwal
*/
-/*
- * NetworkLink.hh
- *
- * Niket Agarwal, Princeton University
- *
- * */
#ifndef NETWORK_LINK_H
#define NETWORK_LINK_H
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.cc b/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.cc
index 9a95971eb..a00dd19c1 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.cc
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * OutVCState.C
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-flexible-pipeline/OutVcState.hh"
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.hh b/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.hh
index cb05826dc..ba68bf2db 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.hh
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/OutVcState.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * OutVCState.hh
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#ifndef OUT_VC_STATE_H
#define OUT_VC_STATE_H
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/Router.cc b/src/mem/ruby/network/garnet-flexible-pipeline/Router.cc
index ea32e938d..628f19349 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/Router.cc
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/Router.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Router.cc
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-flexible-pipeline/Router.hh"
#include "mem/ruby/slicc_interface/NetworkMessage.hh"
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/Router.hh b/src/mem/ruby/network/garnet-flexible-pipeline/Router.hh
index f3cf0036d..69d405ad4 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/Router.hh
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/Router.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Router.hh
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#ifndef ROUTER_H
#define ROUTER_H
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.cc b/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.cc
index 271d6dd38..9064cc4a2 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.cc
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * VCarbiter.C
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-flexible-pipeline/VCarbiter.hh"
#include "mem/ruby/network/garnet-flexible-pipeline/Router.hh"
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.hh b/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.hh
index 96a03b8dc..7f7e5e814 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.hh
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/VCarbiter.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * VCarbiter.hh
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#ifndef VC_ARBITER_H
#define VC_ARBITER_H
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/flit.cc b/src/mem/ruby/network/garnet-flexible-pipeline/flit.cc
index 51b8af6c6..549726348 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/flit.cc
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/flit.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * flit.C
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-flexible-pipeline/flit.hh"
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/flit.hh b/src/mem/ruby/network/garnet-flexible-pipeline/flit.hh
index aeac2e63b..a2e628443 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/flit.hh
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/flit.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * flit.hh
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-fixed-pipeline/NetworkHeader.hh"
#include "mem/ruby/slicc_interface/Message.hh"
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.cc b/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.cc
index a0bb71c9d..c68f8c78b 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.cc
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * flitBuffer.C
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#include "mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh"
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh b/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh
index 006ba60bd..c722e161c 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/flitBuffer.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * Copyright (c) 2008 Princeton University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,14 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * flitBuffer.hh
*
- * Niket Agarwal, Princeton University
- *
- * */
+ * Authors: Niket Agarwal
+ */
#ifndef FLIT_BUFFER_H
#define FLIT_BUFFER_H
diff --git a/src/mem/ruby/network/orion/power_utils.cc b/src/mem/ruby/network/orion/power_utils.cc
index bc69c3cc7..358e13c6f 100644
--- a/src/mem/ruby/network/orion/power_utils.cc
+++ b/src/mem/ruby/network/orion/power_utils.cc
@@ -30,6 +30,7 @@
#include <cmath>
#include <cstdio>
+#include "base/types.hh"
#include "mem/ruby/network/orion/parm_technology.hh"
#include "mem/ruby/network/orion/power_utils.hh"
@@ -39,11 +40,11 @@
static char h_tab[256] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
-static unsigned SIM_power_Hamming_slow( unsigned long int old_val, unsigned long int new_val, unsigned long int mask )
+static uint32_t SIM_power_Hamming_slow( uint64_t old_val, uint64_t new_val, uint64_t mask )
{
/* old slow code, I don't understand the new fast code though */
- /* unsigned long int dist;
- unsigned Hamming = 0;
+ /* uint64_t dist;
+ uint32_t Hamming = 0;
dist = ( old_val ^ new_val ) & mask;
mask = (mask >> 1) + 1;
@@ -58,7 +59,7 @@ static unsigned SIM_power_Hamming_slow( unsigned long int old_val, unsigned long
#define TWO(k) (BIGONE << (k))
#define CYCL(k) (BIGNONE/(1 + (TWO(TWO(k)))))
#define BSUM(x,k) ((x)+=(x) >> TWO(k), (x) &= CYCL(k))
- unsigned long int x;
+ uint64_t x;
x = (old_val ^ new_val) & mask;
x = (x & CYCL(0)) + ((x>>TWO(0)) & CYCL(0));
@@ -74,7 +75,7 @@ static unsigned SIM_power_Hamming_slow( unsigned long int old_val, unsigned long
int SIM_power_init(void)
{
- unsigned i;
+ uint32_t i;
/* initialize Hamming distance table */
for (i = 0; i < 256; i++)
@@ -84,14 +85,16 @@ int SIM_power_init(void)
}
-/* assume unsigned long int is unsigned64_t */
-unsigned SIM_power_Hamming(unsigned long int old_val, unsigned long int new_val, unsigned long int mask)
+
+uint32_t
+SIM_power_Hamming(uint64_t old_val, uint64_t new_val, uint64_t mask)
{
- union {
- unsigned long int x;
- char id[8];
- } u;
- unsigned rval;
+ union {
+ uint64_t x;
+ uint64_t id[8];
+ } u;
+
+ uint32_t rval;
u.x = (old_val ^ new_val) & mask;
@@ -108,10 +111,12 @@ unsigned SIM_power_Hamming(unsigned long int old_val, unsigned long int new_val,
}
-unsigned SIM_power_Hamming_group(unsigned long int d1_new, unsigned long int d1_old, unsigned long int d2_new, unsigned long int d2_old, unsigned width, unsigned n_grp)
+uint32_t
+SIM_power_Hamming_group(uint64_t d1_new, uint64_t d1_old, uint64_t d2_new,
+ uint64_t d2_old, uint32_t width, uint32_t n_grp)
{
- unsigned rval = 0;
- unsigned long int g1_new, g1_old, g2_new, g2_old, mask;
+ uint32_t rval = 0;
+ uint64_t g1_new, g1_old, g2_new, g2_old, mask;
mask = HAMM_MASK(width);
@@ -146,11 +151,12 @@ double logtwo(double x)
return log10(x)/log10(2);
}
-unsigned SIM_power_logtwo(unsigned long int x)
+uint32_t
+SIM_power_logtwo(uint64_t x)
{
- unsigned rval = 0;
+ uint32_t rval = 0;
- while (x >> rval && rval < sizeof(unsigned long int) << 3) rval++;
+ while (x >> rval && rval < sizeof(uint64_t) << 3) rval++;
if (x == (BIGONE << rval - 1)) rval--;
return rval;
diff --git a/src/mem/ruby/network/simple/SimpleNetwork.cc b/src/mem/ruby/network/simple/SimpleNetwork.cc
index 497c602d1..adf7ee21e 100644
--- a/src/mem/ruby/network/simple/SimpleNetwork.cc
+++ b/src/mem/ruby/network/simple/SimpleNetwork.cc
@@ -87,8 +87,10 @@ void SimpleNetwork::init(const vector<string> & argv)
m_toNetQueues[node].setSize(m_virtual_networks);
m_fromNetQueues[node].setSize(m_virtual_networks);
for (int j = 0; j < m_virtual_networks; j++) {
- m_toNetQueues[node][j] = new MessageBuffer;
- m_fromNetQueues[node][j] = new MessageBuffer;
+ m_toNetQueues[node][j] = new MessageBuffer(
+ "toNet node "+int_to_string(node)+" j "+int_to_string(j));
+ m_fromNetQueues[node][j] = new MessageBuffer(
+ "fromNet node "+int_to_string(node)+" j "+int_to_string(j));
}
}
@@ -124,7 +126,7 @@ SimpleNetwork::~SimpleNetwork()
}
m_switch_ptr_vector.deletePointers();
m_buffers_to_free.deletePointers();
- delete m_topology_ptr;
+ // delete m_topology_ptr;
}
// From a switch to an endpoint node
diff --git a/src/mem/slicc/ast/DeclAST.cc b/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.cc
index 6ccf9a9d6..4d37b0007 100644
--- a/src/mem/slicc/ast/DeclAST.cc
+++ b/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.cc
@@ -27,13 +27,12 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * DeclAST.C
- *
- * Description: See DeclAST.hh
- *
- * $Id$
- *
- */
-#include "mem/slicc/ast/DeclAST.hh"
+#include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh"
+#include "mem/ruby/system/CacheMemory.hh"
+
+int getNumberOfLastLevelCaches()
+{
+ return CacheMemory::numberOfLastLevelCaches();
+}
+
diff --git a/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh b/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh
index 159c33815..69424c414 100644
--- a/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh
+++ b/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh
@@ -61,6 +61,15 @@
#define MACHINETYPE_L3CACHE_ENUM MachineType_NUM
#endif
+#ifdef MACHINETYPE_DMA
+#define MACHINETYPE_DMA_ENUM MachineType_DMA
+#else
+#define MACHINETYPE_DMA_ENUM MachineType_NUM
+#endif
+
+// used to determine the number of acks to wait for
+int getNumberOfLastLevelCaches();
+
// used to determine the home directory
// returns a value between 0 and total_directories_within_the_system
inline
@@ -81,7 +90,7 @@ MachineID map_Address_to_Directory(const Address &addr)
inline
MachineID map_Address_to_DMA(const Address & addr)
{
- MachineID dma = {MachineType_DMA, 0};
+ MachineID dma = {MACHINETYPE_DMA_ENUM, 0};
return dma;
}
diff --git a/src/mem/ruby/slicc_interface/SConscript b/src/mem/ruby/slicc_interface/SConscript
index 2b20892ba..6ba614fa9 100644
--- a/src/mem/ruby/slicc_interface/SConscript
+++ b/src/mem/ruby/slicc_interface/SConscript
@@ -35,3 +35,4 @@ if not env['RUBY']:
Source('AbstractCacheEntry.cc')
Source('RubySlicc_Profiler_interface.cc')
+Source('RubySlicc_ComponentMapping.cc')
diff --git a/src/mem/ruby/system/CacheMemory.cc b/src/mem/ruby/system/CacheMemory.cc
new file mode 100644
index 000000000..cf3e094ad
--- /dev/null
+++ b/src/mem/ruby/system/CacheMemory.cc
@@ -0,0 +1,483 @@
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "mem/ruby/system/CacheMemory.hh"
+
+int CacheMemory::m_num_last_level_caches = 0;
+MachineType CacheMemory::m_last_level_machine_type = MachineType_FIRST;
+
+// Output operator declaration
+//ostream& operator<<(ostream& out, const CacheMemory<ENTRY>& obj);
+
+// ******************* Definitions *******************
+
+// Output operator definition
+ostream& operator<<(ostream& out, const CacheMemory& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+
+// ****************************************************************
+
+CacheMemory::CacheMemory(const string & name)
+ : m_cache_name(name)
+{
+ m_profiler_ptr = new CacheProfiler(name);
+}
+
+void CacheMemory::init(const vector<string> & argv)
+{
+ int cache_size = -1;
+ string policy;
+
+ m_num_last_level_caches =
+ MachineType_base_count(MachineType_FIRST);
+ m_controller = NULL;
+ for (uint32 i=0; i<argv.size(); i+=2) {
+ if (argv[i] == "size") {
+ cache_size = atoi(argv[i+1].c_str());
+ } else if (argv[i] == "latency") {
+ m_latency = atoi(argv[i+1].c_str());
+ } else if (argv[i] == "assoc") {
+ m_cache_assoc = atoi(argv[i+1].c_str());
+ } else if (argv[i] == "replacement_policy") {
+ policy = argv[i+1];
+ } else if (argv[i] == "controller") {
+ m_controller = RubySystem::getController(argv[i+1]);
+ if (m_last_level_machine_type < m_controller->getMachineType()) {
+ m_num_last_level_caches =
+ MachineType_base_count(m_controller->getMachineType());
+ m_last_level_machine_type =
+ m_controller->getMachineType();
+ }
+ } else {
+ cerr << "WARNING: CacheMemory: Unknown configuration parameter: " << argv[i] << endl;
+ }
+ }
+
+ int num_lines = cache_size/RubySystem::getBlockSizeBytes();
+ m_cache_num_sets = num_lines / m_cache_assoc;
+ m_cache_num_set_bits = log_int(m_cache_num_sets);
+ assert(m_cache_num_set_bits > 0);
+
+ if(policy == "PSEUDO_LRU")
+ m_replacementPolicy_ptr = new PseudoLRUPolicy(m_cache_num_sets, m_cache_assoc);
+ else if (policy == "LRU")
+ m_replacementPolicy_ptr = new LRUPolicy(m_cache_num_sets, m_cache_assoc);
+ else
+ assert(false);
+
+ m_cache.setSize(m_cache_num_sets);
+ m_locked.setSize(m_cache_num_sets);
+ for (int i = 0; i < m_cache_num_sets; i++) {
+ m_cache[i].setSize(m_cache_assoc);
+ m_locked[i].setSize(m_cache_assoc);
+ for (int j = 0; j < m_cache_assoc; j++) {
+ m_cache[i][j] = NULL;
+ m_locked[i][j] = -1;
+ }
+ }
+}
+
+CacheMemory::~CacheMemory()
+{
+ if(m_replacementPolicy_ptr != NULL)
+ delete m_replacementPolicy_ptr;
+ delete m_profiler_ptr;
+ for (int i = 0; i < m_cache_num_sets; i++) {
+ for (int j = 0; j < m_cache_assoc; j++) {
+ delete m_cache[i][j];
+ }
+ }
+}
+
+int
+CacheMemory::numberOfLastLevelCaches()
+{
+ return m_num_last_level_caches;
+}
+
+
+void CacheMemory::printConfig(ostream& out)
+{
+ out << "Cache config: " << m_cache_name << endl;
+ if (m_controller != NULL)
+ out << " controller: " << m_controller->getName() << endl;
+ out << " cache_associativity: " << m_cache_assoc << endl;
+ out << " num_cache_sets_bits: " << m_cache_num_set_bits << endl;
+ const int cache_num_sets = 1 << m_cache_num_set_bits;
+ out << " num_cache_sets: " << cache_num_sets << endl;
+ out << " cache_set_size_bytes: " << cache_num_sets * RubySystem::getBlockSizeBytes() << endl;
+ out << " cache_set_size_Kbytes: "
+ << double(cache_num_sets * RubySystem::getBlockSizeBytes()) / (1<<10) << endl;
+ out << " cache_set_size_Mbytes: "
+ << double(cache_num_sets * RubySystem::getBlockSizeBytes()) / (1<<20) << endl;
+ out << " cache_size_bytes: "
+ << cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc << endl;
+ out << " cache_size_Kbytes: "
+ << double(cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc) / (1<<10) << endl;
+ out << " cache_size_Mbytes: "
+ << double(cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc) / (1<<20) << endl;
+}
+
+// PRIVATE METHODS
+
+// convert a Address to its location in the cache
+Index CacheMemory::addressToCacheSet(const Address& address) const
+{
+ assert(address == line_address(address));
+ return address.bitSelect(RubySystem::getBlockSizeBits(), RubySystem::getBlockSizeBits() + m_cache_num_set_bits-1);
+}
+
+// Given a cache index: returns the index of the tag in a set.
+// returns -1 if the tag is not found.
+int CacheMemory::findTagInSet(Index cacheSet, const Address& tag) const
+{
+ assert(tag == line_address(tag));
+ // search the set for the tags
+ m5::hash_map<Address, int>::const_iterator it = m_tag_index.find(tag);
+ if (it != m_tag_index.end())
+ if (m_cache[cacheSet][it->second]->m_Permission != AccessPermission_NotPresent)
+ return it->second;
+ return -1; // Not found
+}
+
+// Given a cache index: returns the index of the tag in a set.
+// returns -1 if the tag is not found.
+int CacheMemory::findTagInSetIgnorePermissions(Index cacheSet, const Address& tag) const
+{
+ assert(tag == line_address(tag));
+ // search the set for the tags
+ m5::hash_map<Address, int>::const_iterator it = m_tag_index.find(tag);
+ if (it != m_tag_index.end())
+ return it->second;
+ return -1; // Not found
+}
+
+// PUBLIC METHODS
+bool CacheMemory::tryCacheAccess(const Address& address,
+ CacheRequestType type,
+ DataBlock*& data_ptr)
+{
+ assert(address == line_address(address));
+ DEBUG_EXPR(CACHE_COMP, HighPrio, address);
+ Index cacheSet = addressToCacheSet(address);
+ int loc = findTagInSet(cacheSet, address);
+ if(loc != -1){ // Do we even have a tag match?
+ AbstractCacheEntry* entry = m_cache[cacheSet][loc];
+ m_replacementPolicy_ptr->touch(cacheSet, loc, g_eventQueue_ptr->getTime());
+ data_ptr = &(entry->getDataBlk());
+
+ if(entry->m_Permission == AccessPermission_Read_Write) {
+ return true;
+ }
+ if ((entry->m_Permission == AccessPermission_Read_Only) &&
+ (type == CacheRequestType_LD || type == CacheRequestType_IFETCH)) {
+ return true;
+ }
+ // The line must not be accessible
+ }
+ data_ptr = NULL;
+ return false;
+}
+
+bool CacheMemory::testCacheAccess(const Address& address,
+ CacheRequestType type,
+ DataBlock*& data_ptr)
+{
+ assert(address == line_address(address));
+ DEBUG_EXPR(CACHE_COMP, HighPrio, address);
+ Index cacheSet = addressToCacheSet(address);
+ int loc = findTagInSet(cacheSet, address);
+ if(loc != -1){ // Do we even have a tag match?
+ AbstractCacheEntry* entry = m_cache[cacheSet][loc];
+ m_replacementPolicy_ptr->touch(cacheSet, loc, g_eventQueue_ptr->getTime());
+ data_ptr = &(entry->getDataBlk());
+
+ return (m_cache[cacheSet][loc]->m_Permission != AccessPermission_NotPresent);
+ }
+ data_ptr = NULL;
+ return false;
+}
+
+// tests to see if an address is present in the cache
+bool CacheMemory::isTagPresent(const Address& address) const
+{
+ assert(address == line_address(address));
+ Index cacheSet = addressToCacheSet(address);
+ int location = findTagInSet(cacheSet, address);
+
+ if (location == -1) {
+ // We didn't find the tag
+ DEBUG_EXPR(CACHE_COMP, LowPrio, address);
+ DEBUG_MSG(CACHE_COMP, LowPrio, "No tag match");
+ return false;
+ }
+ DEBUG_EXPR(CACHE_COMP, LowPrio, address);
+ DEBUG_MSG(CACHE_COMP, LowPrio, "found");
+ return true;
+}
+
+// Returns true if there is:
+// a) a tag match on this address or there is
+// b) an unused line in the same cache "way"
+bool CacheMemory::cacheAvail(const Address& address) const
+{
+ assert(address == line_address(address));
+
+ Index cacheSet = addressToCacheSet(address);
+
+ for (int i=0; i < m_cache_assoc; i++) {
+ AbstractCacheEntry* entry = m_cache[cacheSet][i];
+ if (entry != NULL) {
+ if (entry->m_Address == address || // Already in the cache
+ entry->m_Permission == AccessPermission_NotPresent) { // We found an empty entry
+ return true;
+ }
+ } else {
+ return true;
+ }
+ }
+ return false;
+}
+
+void CacheMemory::allocate(const Address& address, AbstractCacheEntry* entry)
+{
+ assert(address == line_address(address));
+ assert(!isTagPresent(address));
+ assert(cacheAvail(address));
+ DEBUG_EXPR(CACHE_COMP, HighPrio, address);
+
+ // Find the first open slot
+ Index cacheSet = addressToCacheSet(address);
+ for (int i=0; i < m_cache_assoc; i++) {
+ if (m_cache[cacheSet][i] == NULL ||
+ m_cache[cacheSet][i]->m_Permission == AccessPermission_NotPresent) {
+ m_cache[cacheSet][i] = entry; // Init entry
+ m_cache[cacheSet][i]->m_Address = address;
+ m_cache[cacheSet][i]->m_Permission = AccessPermission_Invalid;
+ m_locked[cacheSet][i] = -1;
+ m_tag_index[address] = i;
+
+ m_replacementPolicy_ptr->touch(cacheSet, i, g_eventQueue_ptr->getTime());
+
+ return;
+ }
+ }
+ ERROR_MSG("Allocate didn't find an available entry");
+}
+
+void CacheMemory::deallocate(const Address& address)
+{
+ assert(address == line_address(address));
+ assert(isTagPresent(address));
+ DEBUG_EXPR(CACHE_COMP, HighPrio, address);
+ Index cacheSet = addressToCacheSet(address);
+ int location = findTagInSet(cacheSet, address);
+ if (location != -1){
+ delete m_cache[cacheSet][location];
+ m_cache[cacheSet][location] = NULL;
+ m_locked[cacheSet][location] = -1;
+ m_tag_index.erase(address);
+ }
+}
+
+// Returns with the physical address of the conflicting cache line
+Address CacheMemory::cacheProbe(const Address& address) const
+{
+ assert(address == line_address(address));
+ assert(!cacheAvail(address));
+
+ Index cacheSet = addressToCacheSet(address);
+ return m_cache[cacheSet][m_replacementPolicy_ptr->getVictim(cacheSet)]->m_Address;
+}
+
+// looks an address up in the cache
+AbstractCacheEntry& CacheMemory::lookup(const Address& address)
+{
+ assert(address == line_address(address));
+ Index cacheSet = addressToCacheSet(address);
+ int loc = findTagInSet(cacheSet, address);
+ assert(loc != -1);
+ return *m_cache[cacheSet][loc];
+}
+
+// looks an address up in the cache
+const AbstractCacheEntry& CacheMemory::lookup(const Address& address) const
+{
+ assert(address == line_address(address));
+ Index cacheSet = addressToCacheSet(address);
+ int loc = findTagInSet(cacheSet, address);
+ assert(loc != -1);
+ return *m_cache[cacheSet][loc];
+}
+
+AccessPermission CacheMemory::getPermission(const Address& address) const
+{
+ assert(address == line_address(address));
+ return lookup(address).m_Permission;
+}
+
+void CacheMemory::changePermission(const Address& address, AccessPermission new_perm)
+{
+ assert(address == line_address(address));
+ lookup(address).m_Permission = new_perm;
+ Index cacheSet = addressToCacheSet(address);
+ int loc = findTagInSet(cacheSet, address);
+ m_locked[cacheSet][loc] = -1;
+ assert(getPermission(address) == new_perm);
+}
+
+// Sets the most recently used bit for a cache block
+void CacheMemory::setMRU(const Address& address)
+{
+ Index cacheSet;
+
+ cacheSet = addressToCacheSet(address);
+ m_replacementPolicy_ptr->touch(cacheSet,
+ findTagInSet(cacheSet, address),
+ g_eventQueue_ptr->getTime());
+}
+
+void CacheMemory::profileMiss(const CacheMsg & msg)
+{
+ m_profiler_ptr->addStatSample(msg.getType(), msg.getAccessMode(),
+ msg.getSize(), msg.getPrefetch());
+}
+
+void CacheMemory::recordCacheContents(CacheRecorder& tr) const
+{
+ for (int i = 0; i < m_cache_num_sets; i++) {
+ for (int j = 0; j < m_cache_assoc; j++) {
+ AccessPermission perm = m_cache[i][j]->m_Permission;
+ CacheRequestType request_type = CacheRequestType_NULL;
+ if (perm == AccessPermission_Read_Only) {
+ if (m_is_instruction_only_cache) {
+ request_type = CacheRequestType_IFETCH;
+ } else {
+ request_type = CacheRequestType_LD;
+ }
+ } else if (perm == AccessPermission_Read_Write) {
+ request_type = CacheRequestType_ST;
+ }
+
+ if (request_type != CacheRequestType_NULL) {
+ // tr.addRecord(m_chip_ptr->getID(), m_cache[i][j].m_Address,
+ // Address(0), request_type, m_replacementPolicy_ptr->getLastAccess(i, j));
+ }
+ }
+ }
+}
+
+void CacheMemory::print(ostream& out) const
+{
+ out << "Cache dump: " << m_cache_name << endl;
+ for (int i = 0; i < m_cache_num_sets; i++) {
+ for (int j = 0; j < m_cache_assoc; j++) {
+ if (m_cache[i][j] != NULL) {
+ out << " Index: " << i
+ << " way: " << j
+ << " entry: " << *m_cache[i][j] << endl;
+ } else {
+ out << " Index: " << i
+ << " way: " << j
+ << " entry: NULL" << endl;
+ }
+ }
+ }
+}
+
+void CacheMemory::printData(ostream& out) const
+{
+ out << "printData() not supported" << endl;
+}
+
+void CacheMemory::clearStats() const
+{
+ m_profiler_ptr->clearStats();
+}
+
+void CacheMemory::printStats(ostream& out) const
+{
+ m_profiler_ptr->printStats(out);
+}
+
+void CacheMemory::getMemoryValue(const Address& addr, char* value,
+ unsigned int size_in_bytes ){
+ AbstractCacheEntry& entry = lookup(line_address(addr));
+ unsigned int startByte = addr.getAddress() - line_address(addr).getAddress();
+ for(unsigned int i=0; i<size_in_bytes; ++i){
+ value[i] = entry.getDataBlk().getByte(i + startByte);
+ }
+}
+
+void CacheMemory::setMemoryValue(const Address& addr, char* value,
+ unsigned int size_in_bytes ){
+ AbstractCacheEntry& entry = lookup(line_address(addr));
+ unsigned int startByte = addr.getAddress() - line_address(addr).getAddress();
+ assert(size_in_bytes > 0);
+ for(unsigned int i=0; i<size_in_bytes; ++i){
+ entry.getDataBlk().setByte(i + startByte, value[i]);
+ }
+
+ // entry = lookup(line_address(addr));
+}
+
+void
+CacheMemory::setLocked(const Address& address, int context)
+{
+ assert(address == line_address(address));
+ Index cacheSet = addressToCacheSet(address);
+ int loc = findTagInSet(cacheSet, address);
+ assert(loc != -1);
+ m_locked[cacheSet][loc] = context;
+}
+
+void
+CacheMemory::clearLocked(const Address& address)
+{
+ assert(address == line_address(address));
+ Index cacheSet = addressToCacheSet(address);
+ int loc = findTagInSet(cacheSet, address);
+ assert(loc != -1);
+ m_locked[cacheSet][loc] = -1;
+}
+
+bool
+CacheMemory::isLocked(const Address& address, int context)
+{
+ assert(address == line_address(address));
+ Index cacheSet = addressToCacheSet(address);
+ int loc = findTagInSet(cacheSet, address);
+ assert(loc != -1);
+ return m_locked[cacheSet][loc] == context;
+}
+
diff --git a/src/mem/ruby/system/CacheMemory.hh b/src/mem/ruby/system/CacheMemory.hh
index 7268189ea..8b84f33ec 100644
--- a/src/mem/ruby/system/CacheMemory.hh
+++ b/src/mem/ruby/system/CacheMemory.hh
@@ -54,6 +54,7 @@
#include "mem/ruby/slicc_interface/AbstractController.hh"
#include "mem/ruby/profiler/CacheProfiler.hh"
#include "mem/protocol/CacheMsg.hh"
+#include "base/hashmap.hh"
#include <vector>
class CacheMemory {
@@ -104,6 +105,8 @@ public:
AccessPermission getPermission(const Address& address) const;
void changePermission(const Address& address, AccessPermission new_perm);
+ static int numberOfLastLevelCaches();
+
int getLatency() const { return m_latency; }
// Hook for checkpointing the contents of the cache
@@ -169,465 +172,11 @@ private:
int m_cache_assoc;
static Vector< CacheMemory* > m_all_caches;
-};
+
+ static int m_num_last_level_caches;
+ static MachineType m_last_level_machine_type;
-// Output operator declaration
-//ostream& operator<<(ostream& out, const CacheMemory<ENTRY>& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-inline
-ostream& operator<<(ostream& out, const CacheMemory& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-
-// ****************************************************************
-
-inline
-CacheMemory::CacheMemory(const string & name)
- : m_cache_name(name)
-{
- m_profiler_ptr = new CacheProfiler(name);
-}
-
-inline
-void CacheMemory::init(const vector<string> & argv)
-{
- int cache_size = 0;
- string policy;
-
- m_controller = NULL;
- for (uint32 i=0; i<argv.size(); i+=2) {
- if (argv[i] == "size_kb") {
- cache_size = atoi(argv[i+1].c_str());
- } else if (argv[i] == "latency") {
- m_latency = atoi(argv[i+1].c_str());
- } else if (argv[i] == "assoc") {
- m_cache_assoc = atoi(argv[i+1].c_str());
- } else if (argv[i] == "replacement_policy") {
- policy = argv[i+1];
- } else if (argv[i] == "controller") {
- m_controller = RubySystem::getController(argv[i+1]);
- } else {
- cerr << "WARNING: CacheMemory: Unknown configuration parameter: " << argv[i] << endl;
- }
- }
-
- int num_lines = (cache_size*1024)/RubySystem::getBlockSizeBytes();
- m_cache_num_sets = num_lines / m_cache_assoc;
- m_cache_num_set_bits = log_int(m_cache_num_sets);
-
- if(policy == "PSEUDO_LRU")
- m_replacementPolicy_ptr = new PseudoLRUPolicy(m_cache_num_sets, m_cache_assoc);
- else if (policy == "LRU")
- m_replacementPolicy_ptr = new LRUPolicy(m_cache_num_sets, m_cache_assoc);
- else
- assert(false);
-
- m_cache.setSize(m_cache_num_sets);
- m_locked.setSize(m_cache_num_sets);
- for (int i = 0; i < m_cache_num_sets; i++) {
- m_cache[i].setSize(m_cache_assoc);
- m_locked[i].setSize(m_cache_assoc);
- for (int j = 0; j < m_cache_assoc; j++) {
- m_cache[i][j] = NULL;
- m_locked[i][j] = -1;
- }
- }
-}
-
-inline
-CacheMemory::~CacheMemory()
-{
- if(m_replacementPolicy_ptr != NULL)
- delete m_replacementPolicy_ptr;
-}
-
-inline
-void CacheMemory::printConfig(ostream& out)
-{
- out << "Cache config: " << m_cache_name << endl;
- if (m_controller != NULL)
- out << " controller: " << m_controller->getName() << endl;
- out << " cache_associativity: " << m_cache_assoc << endl;
- out << " num_cache_sets_bits: " << m_cache_num_set_bits << endl;
- const int cache_num_sets = 1 << m_cache_num_set_bits;
- out << " num_cache_sets: " << cache_num_sets << endl;
- out << " cache_set_size_bytes: " << cache_num_sets * RubySystem::getBlockSizeBytes() << endl;
- out << " cache_set_size_Kbytes: "
- << double(cache_num_sets * RubySystem::getBlockSizeBytes()) / (1<<10) << endl;
- out << " cache_set_size_Mbytes: "
- << double(cache_num_sets * RubySystem::getBlockSizeBytes()) / (1<<20) << endl;
- out << " cache_size_bytes: "
- << cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc << endl;
- out << " cache_size_Kbytes: "
- << double(cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc) / (1<<10) << endl;
- out << " cache_size_Mbytes: "
- << double(cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc) / (1<<20) << endl;
-}
-
-// PRIVATE METHODS
-
-// convert a Address to its location in the cache
-inline
-Index CacheMemory::addressToCacheSet(const Address& address) const
-{
- assert(address == line_address(address));
- return address.bitSelect(RubySystem::getBlockSizeBits(), RubySystem::getBlockSizeBits() + m_cache_num_set_bits-1);
-}
-
-// Given a cache index: returns the index of the tag in a set.
-// returns -1 if the tag is not found.
-inline
-int CacheMemory::findTagInSet(Index cacheSet, const Address& tag) const
-{
- assert(tag == line_address(tag));
- // search the set for the tags
- m5::hash_map<Address, int>::const_iterator it = m_tag_index.find(tag);
- if (it != m_tag_index.end())
- if (m_cache[cacheSet][it->second]->m_Permission != AccessPermission_NotPresent)
- return it->second;
- return -1; // Not found
-}
-
-// Given a cache index: returns the index of the tag in a set.
-// returns -1 if the tag is not found.
-inline
-int CacheMemory::findTagInSetIgnorePermissions(Index cacheSet, const Address& tag) const
-{
- assert(tag == line_address(tag));
- // search the set for the tags
- m5::hash_map<Address, int>::const_iterator it = m_tag_index.find(tag);
- if (it != m_tag_index.end())
- return it->second;
- return -1; // Not found
-}
-
-// PUBLIC METHODS
-inline
-bool CacheMemory::tryCacheAccess(const Address& address,
- CacheRequestType type,
- DataBlock*& data_ptr)
-{
- assert(address == line_address(address));
- DEBUG_EXPR(CACHE_COMP, HighPrio, address);
- Index cacheSet = addressToCacheSet(address);
- int loc = findTagInSet(cacheSet, address);
- if(loc != -1){ // Do we even have a tag match?
- AbstractCacheEntry* entry = m_cache[cacheSet][loc];
- m_replacementPolicy_ptr->touch(cacheSet, loc, g_eventQueue_ptr->getTime());
- data_ptr = &(entry->getDataBlk());
-
- if(entry->m_Permission == AccessPermission_Read_Write) {
- return true;
- }
- if ((entry->m_Permission == AccessPermission_Read_Only) &&
- (type == CacheRequestType_LD || type == CacheRequestType_IFETCH)) {
- return true;
- }
- // The line must not be accessible
- }
- data_ptr = NULL;
- return false;
-}
-
-inline
-bool CacheMemory::testCacheAccess(const Address& address,
- CacheRequestType type,
- DataBlock*& data_ptr)
-{
- assert(address == line_address(address));
- DEBUG_EXPR(CACHE_COMP, HighPrio, address);
- Index cacheSet = addressToCacheSet(address);
- int loc = findTagInSet(cacheSet, address);
- if(loc != -1){ // Do we even have a tag match?
- AbstractCacheEntry* entry = m_cache[cacheSet][loc];
- m_replacementPolicy_ptr->touch(cacheSet, loc, g_eventQueue_ptr->getTime());
- data_ptr = &(entry->getDataBlk());
-
- return (m_cache[cacheSet][loc]->m_Permission != AccessPermission_NotPresent);
- }
- data_ptr = NULL;
- return false;
-}
-
-// tests to see if an address is present in the cache
-inline
-bool CacheMemory::isTagPresent(const Address& address) const
-{
- assert(address == line_address(address));
- Index cacheSet = addressToCacheSet(address);
- int location = findTagInSet(cacheSet, address);
-
- if (location == -1) {
- // We didn't find the tag
- DEBUG_EXPR(CACHE_COMP, LowPrio, address);
- DEBUG_MSG(CACHE_COMP, LowPrio, "No tag match");
- return false;
- }
- DEBUG_EXPR(CACHE_COMP, LowPrio, address);
- DEBUG_MSG(CACHE_COMP, LowPrio, "found");
- return true;
-}
-
-// Returns true if there is:
-// a) a tag match on this address or there is
-// b) an unused line in the same cache "way"
-inline
-bool CacheMemory::cacheAvail(const Address& address) const
-{
- assert(address == line_address(address));
-
- Index cacheSet = addressToCacheSet(address);
-
- for (int i=0; i < m_cache_assoc; i++) {
- AbstractCacheEntry* entry = m_cache[cacheSet][i];
- if (entry != NULL) {
- if (entry->m_Address == address || // Already in the cache
- entry->m_Permission == AccessPermission_NotPresent) { // We found an empty entry
- return true;
- }
- } else {
- return true;
- }
- }
- return false;
-}
-
-inline
-void CacheMemory::allocate(const Address& address, AbstractCacheEntry* entry)
-{
- assert(address == line_address(address));
- assert(!isTagPresent(address));
- assert(cacheAvail(address));
- DEBUG_EXPR(CACHE_COMP, HighPrio, address);
-
- // Find the first open slot
- Index cacheSet = addressToCacheSet(address);
- for (int i=0; i < m_cache_assoc; i++) {
- if (m_cache[cacheSet][i] == NULL ||
- m_cache[cacheSet][i]->m_Permission == AccessPermission_NotPresent) {
- m_cache[cacheSet][i] = entry; // Init entry
- m_cache[cacheSet][i]->m_Address = address;
- m_cache[cacheSet][i]->m_Permission = AccessPermission_Invalid;
- m_locked[cacheSet][i] = -1;
- m_tag_index[address] = i;
-
- m_replacementPolicy_ptr->touch(cacheSet, i, g_eventQueue_ptr->getTime());
-
- return;
- }
- }
- ERROR_MSG("Allocate didn't find an available entry");
-}
-
-inline
-void CacheMemory::deallocate(const Address& address)
-{
- assert(address == line_address(address));
- assert(isTagPresent(address));
- DEBUG_EXPR(CACHE_COMP, HighPrio, address);
- Index cacheSet = addressToCacheSet(address);
- int location = findTagInSet(cacheSet, address);
- if (location != -1){
- delete m_cache[cacheSet][location];
- m_cache[cacheSet][location] = NULL;
- m_locked[cacheSet][location] = -1;
- m_tag_index.erase(address);
- }
-}
-
-// Returns with the physical address of the conflicting cache line
-inline
-Address CacheMemory::cacheProbe(const Address& address) const
-{
- assert(address == line_address(address));
- assert(!cacheAvail(address));
-
- Index cacheSet = addressToCacheSet(address);
- return m_cache[cacheSet][m_replacementPolicy_ptr->getVictim(cacheSet)]->m_Address;
-}
-
-// looks an address up in the cache
-inline
-AbstractCacheEntry& CacheMemory::lookup(const Address& address)
-{
- assert(address == line_address(address));
- Index cacheSet = addressToCacheSet(address);
- int loc = findTagInSet(cacheSet, address);
- assert(loc != -1);
- return *m_cache[cacheSet][loc];
-}
-
-// looks an address up in the cache
-inline
-const AbstractCacheEntry& CacheMemory::lookup(const Address& address) const
-{
- assert(address == line_address(address));
- Index cacheSet = addressToCacheSet(address);
- int loc = findTagInSet(cacheSet, address);
- assert(loc != -1);
- return *m_cache[cacheSet][loc];
-}
-
-inline
-AccessPermission CacheMemory::getPermission(const Address& address) const
-{
- assert(address == line_address(address));
- return lookup(address).m_Permission;
-}
-
-inline
-void CacheMemory::changePermission(const Address& address, AccessPermission new_perm)
-{
- assert(address == line_address(address));
- lookup(address).m_Permission = new_perm;
- Index cacheSet = addressToCacheSet(address);
- int loc = findTagInSet(cacheSet, address);
- m_locked[cacheSet][loc] = -1;
- assert(getPermission(address) == new_perm);
-}
-
-// Sets the most recently used bit for a cache block
-inline
-void CacheMemory::setMRU(const Address& address)
-{
- Index cacheSet;
-
- cacheSet = addressToCacheSet(address);
- m_replacementPolicy_ptr->touch(cacheSet,
- findTagInSet(cacheSet, address),
- g_eventQueue_ptr->getTime());
-}
-
-inline
-void CacheMemory::profileMiss(const CacheMsg & msg)
-{
- m_profiler_ptr->addStatSample(msg.getType(), msg.getAccessMode(),
- msg.getSize(), msg.getPrefetch());
-}
-
-inline
-void CacheMemory::recordCacheContents(CacheRecorder& tr) const
-{
- for (int i = 0; i < m_cache_num_sets; i++) {
- for (int j = 0; j < m_cache_assoc; j++) {
- AccessPermission perm = m_cache[i][j]->m_Permission;
- CacheRequestType request_type = CacheRequestType_NULL;
- if (perm == AccessPermission_Read_Only) {
- if (m_is_instruction_only_cache) {
- request_type = CacheRequestType_IFETCH;
- } else {
- request_type = CacheRequestType_LD;
- }
- } else if (perm == AccessPermission_Read_Write) {
- request_type = CacheRequestType_ST;
- }
-
- if (request_type != CacheRequestType_NULL) {
- // tr.addRecord(m_chip_ptr->getID(), m_cache[i][j].m_Address,
- // Address(0), request_type, m_replacementPolicy_ptr->getLastAccess(i, j));
- }
- }
- }
-}
-
-inline
-void CacheMemory::print(ostream& out) const
-{
- out << "Cache dump: " << m_cache_name << endl;
- for (int i = 0; i < m_cache_num_sets; i++) {
- for (int j = 0; j < m_cache_assoc; j++) {
- if (m_cache[i][j] != NULL) {
- out << " Index: " << i
- << " way: " << j
- << " entry: " << *m_cache[i][j] << endl;
- } else {
- out << " Index: " << i
- << " way: " << j
- << " entry: NULL" << endl;
- }
- }
- }
-}
-
-inline
-void CacheMemory::printData(ostream& out) const
-{
- out << "printData() not supported" << endl;
-}
-
-inline void CacheMemory::clearStats() const
-{
- m_profiler_ptr->clearStats();
-}
-
-inline
-void CacheMemory::printStats(ostream& out) const
-{
- m_profiler_ptr->printStats(out);
-}
-
-inline
-void CacheMemory::getMemoryValue(const Address& addr, char* value,
- unsigned int size_in_bytes ){
- AbstractCacheEntry& entry = lookup(line_address(addr));
- unsigned int startByte = addr.getAddress() - line_address(addr).getAddress();
- for(unsigned int i=0; i<size_in_bytes; ++i){
- value[i] = entry.getDataBlk().getByte(i + startByte);
- }
-}
-
-inline
-void CacheMemory::setMemoryValue(const Address& addr, char* value,
- unsigned int size_in_bytes ){
- AbstractCacheEntry& entry = lookup(line_address(addr));
- unsigned int startByte = addr.getAddress() - line_address(addr).getAddress();
- assert(size_in_bytes > 0);
- for(unsigned int i=0; i<size_in_bytes; ++i){
- entry.getDataBlk().setByte(i + startByte, value[i]);
- }
-
- // entry = lookup(line_address(addr));
-}
-
-inline
-void
-CacheMemory::setLocked(const Address& address, int context)
-{
- assert(address == line_address(address));
- Index cacheSet = addressToCacheSet(address);
- int loc = findTagInSet(cacheSet, address);
- assert(loc != -1);
- m_locked[cacheSet][loc] = context;
-}
-
-inline
-void
-CacheMemory::clearLocked(const Address& address)
-{
- assert(address == line_address(address));
- Index cacheSet = addressToCacheSet(address);
- int loc = findTagInSet(cacheSet, address);
- assert(loc != -1);
- m_locked[cacheSet][loc] = -1;
-}
-
-inline
-bool
-CacheMemory::isLocked(const Address& address, int context)
-{
- assert(address == line_address(address));
- Index cacheSet = addressToCacheSet(address);
- int loc = findTagInSet(cacheSet, address);
- assert(loc != -1);
- return m_locked[cacheSet][loc] == context;
-}
+};
#endif //CACHEMEMORY_H
diff --git a/src/mem/ruby/system/DirectoryMemory.cc b/src/mem/ruby/system/DirectoryMemory.cc
index 46ebdbab4..9b2a3873c 100644
--- a/src/mem/ruby/system/DirectoryMemory.cc
+++ b/src/mem/ruby/system/DirectoryMemory.cc
@@ -84,11 +84,14 @@ void DirectoryMemory::init(const vector<string> & argv)
DirectoryMemory::~DirectoryMemory()
{
// free up all the directory entries
- for (int i=0;i<m_num_entries;i++)
- if (m_entries[i] != NULL)
- delete m_entries;
- if (m_entries != NULL)
+ for (uint64 i=0;i<m_num_entries;i++) {
+ if (m_entries[i] != NULL) {
+ delete m_entries[i];
+ }
+ }
+ if (m_entries != NULL) {
delete [] m_entries;
+ }
}
void DirectoryMemory::printConfig(ostream& out) const
diff --git a/src/mem/ruby/system/PersistentTable.cc b/src/mem/ruby/system/PersistentTable.cc
new file mode 100644
index 000000000..58b67ea60
--- /dev/null
+++ b/src/mem/ruby/system/PersistentTable.cc
@@ -0,0 +1,204 @@
+
+/*
+ * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "mem/ruby/system/PersistentTable.hh"
+#include "mem/gems_common/util.hh"
+
+// randomize so that handoffs are not locality-aware
+// int persistent_randomize[] = {0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15};
+// int persistent_randomize[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+
+
+PersistentTable::PersistentTable()
+{
+ m_map_ptr = new Map<Address, PersistentTableEntry>;
+}
+
+PersistentTable::~PersistentTable()
+{
+ delete m_map_ptr;
+ m_map_ptr = NULL;
+}
+
+void PersistentTable::persistentRequestLock(const Address& address,
+ MachineID locker,
+ AccessType type)
+{
+
+ // if (locker == m_chip_ptr->getID() )
+ // cout << "Chip " << m_chip_ptr->getID() << ": " << llocker
+ // << " requesting lock for " << address << endl;
+
+ // MachineID locker = (MachineID) persistent_randomize[llocker];
+
+ assert(address == line_address(address));
+ if (!m_map_ptr->exist(address)) {
+ // Allocate if not present
+ PersistentTableEntry entry;
+ entry.m_starving.add(locker);
+ if (type == AccessType_Write) {
+ entry.m_request_to_write.add(locker);
+ }
+ m_map_ptr->add(address, entry);
+ } else {
+ PersistentTableEntry& entry = m_map_ptr->lookup(address);
+
+ //
+ // Make sure we're not already in the locked set
+ //
+ assert(!(entry.m_starving.isElement(locker)));
+
+ entry.m_starving.add(locker);
+ if (type == AccessType_Write) {
+ entry.m_request_to_write.add(locker);
+ }
+ assert(entry.m_marked.isSubset(entry.m_starving));
+ }
+}
+
+void PersistentTable::persistentRequestUnlock(const Address& address,
+ MachineID unlocker)
+{
+ // if (unlocker == m_chip_ptr->getID() )
+ // cout << "Chip " << m_chip_ptr->getID() << ": " << uunlocker
+ // << " requesting unlock for " << address << endl;
+
+ // MachineID unlocker = (MachineID) persistent_randomize[uunlocker];
+
+ assert(address == line_address(address));
+ assert(m_map_ptr->exist(address));
+ PersistentTableEntry& entry = m_map_ptr->lookup(address);
+
+ //
+ // Make sure we're in the locked set
+ //
+ assert(entry.m_starving.isElement(unlocker));
+ assert(entry.m_marked.isSubset(entry.m_starving));
+ entry.m_starving.remove(unlocker);
+ entry.m_marked.remove(unlocker);
+ entry.m_request_to_write.remove(unlocker);
+ assert(entry.m_marked.isSubset(entry.m_starving));
+
+ // Deallocate if empty
+ if (entry.m_starving.isEmpty()) {
+ assert(entry.m_marked.isEmpty());
+ m_map_ptr->erase(address);
+ }
+}
+
+bool PersistentTable::okToIssueStarving(const Address& address,
+ MachineID machId) const
+{
+ assert(address == line_address(address));
+ if (!m_map_ptr->exist(address)) {
+ //
+ // No entry present
+ //
+ return true;
+ } else if (m_map_ptr->lookup(address).m_starving.isElement(machId)) {
+ //
+ // We can't issue another lockdown until are previous unlock has occurred
+ //
+ return false;
+ } else {
+ return (m_map_ptr->lookup(address).m_marked.isEmpty());
+ }
+}
+
+MachineID PersistentTable::findSmallest(const Address& address) const
+{
+ assert(address == line_address(address));
+ assert(m_map_ptr->exist(address));
+ const PersistentTableEntry& entry = m_map_ptr->lookup(address);
+ return entry.m_starving.smallestElement();
+}
+
+AccessType PersistentTable::typeOfSmallest(const Address& address) const
+{
+ assert(address == line_address(address));
+ assert(m_map_ptr->exist(address));
+ const PersistentTableEntry& entry = m_map_ptr->lookup(address);
+ if (entry.m_request_to_write.isElement(entry.m_starving.smallestElement())) {
+ return AccessType_Write;
+ } else {
+ return AccessType_Read;
+ }
+}
+
+void PersistentTable::markEntries(const Address& address)
+{
+ assert(address == line_address(address));
+ if (m_map_ptr->exist(address)) {
+ PersistentTableEntry& entry = m_map_ptr->lookup(address);
+
+ //
+ // None should be marked
+ //
+ assert(entry.m_marked.isEmpty());
+
+ //
+ // Mark all the nodes currently in the table
+ //
+ entry.m_marked = entry.m_starving;
+ }
+}
+
+bool PersistentTable::isLocked(const Address& address) const
+{
+ assert(address == line_address(address));
+ // If an entry is present, it must be locked
+ return (m_map_ptr->exist(address));
+}
+
+int PersistentTable::countStarvingForAddress(const Address& address) const
+{
+ if (m_map_ptr->exist(address)) {
+ PersistentTableEntry& entry = m_map_ptr->lookup(address);
+ return (entry.m_starving.count());
+ }
+ else {
+ return 0;
+ }
+}
+
+int PersistentTable::countReadStarvingForAddress(const Address& address) const
+{
+ if (m_map_ptr->exist(address)) {
+ PersistentTableEntry& entry = m_map_ptr->lookup(address);
+ return (entry.m_starving.count() - entry.m_request_to_write.count());
+ }
+ else {
+ return 0;
+ }
+}
+
+void PersistentTable::print(ostream& out) const
+{
+}
+
diff --git a/src/mem/slicc/ast/InfixOperatorExprAST.hh b/src/mem/ruby/system/PersistentTable.hh
index f97ab8805..8cbb48817 100644
--- a/src/mem/slicc/ast/InfixOperatorExprAST.hh
+++ b/src/mem/ruby/system/PersistentTable.hh
@@ -27,59 +27,76 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * InfixOperatorExprAST.hh
- *
- * Description:
- *
- * $Id: InfixOperatorExprAST.hh,v 3.1 2001/12/12 01:00:19 milo Exp $
- *
- */
+#ifndef PersistentTable_H
+#define PersistentTable_H
-#ifndef INFIXOPERATOREXPRAST_H
-#define INFIXOPERATOREXPRAST_H
+#include "mem/ruby/common/Global.hh"
+#include "mem/gems_common/Map.hh"
+#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/system/MachineID.hh"
+#include "mem/protocol/AccessType.hh"
+#include "mem/ruby/common/NetDest.hh"
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/ExprAST.hh"
+class PersistentTableEntry {
+public:
+ void print(ostream& out) const {}
+ NetDest m_starving;
+ NetDest m_marked;
+ NetDest m_request_to_write;
+};
-class InfixOperatorExprAST : public ExprAST {
+class PersistentTable {
public:
// Constructors
- InfixOperatorExprAST(ExprAST* left_ptr, string* op_ptr, ExprAST* right_ptr);
+ PersistentTable();
// Destructor
- ~InfixOperatorExprAST();
-
+ ~PersistentTable();
+
// Public Methods
- Type* generate(string& code) const;
+ void persistentRequestLock(const Address& address, MachineID locker, AccessType type);
+ void persistentRequestUnlock(const Address& address, MachineID unlocker);
+ bool okToIssueStarving(const Address& address, MachineID machID) const;
+ MachineID findSmallest(const Address& address) const;
+ AccessType typeOfSmallest(const Address& address) const;
+ void markEntries(const Address& address);
+ bool isLocked(const Address& addr) const;
+ int countStarvingForAddress(const Address& addr) const;
+ int countReadStarvingForAddress(const Address& addr) const;
+
+ static void printConfig(ostream& out) {}
+
void print(ostream& out) const;
private:
// Private Methods
// Private copy constructor and assignment operator
- InfixOperatorExprAST(const InfixOperatorExprAST& obj);
- InfixOperatorExprAST& operator=(const InfixOperatorExprAST& obj);
-
- // Data Members (m_ prefix)
- ExprAST* m_left_ptr;
- string* m_op_ptr;
- ExprAST* m_right_ptr;
+ PersistentTable(const PersistentTable& obj);
+ PersistentTable& operator=(const PersistentTable& obj);
+ // Data Members (m_prefix)
+ Map<Address, PersistentTableEntry>* m_map_ptr;
};
-// Output operator declaration
-ostream& operator<<(ostream& out, const InfixOperatorExprAST& obj);
-
// ******************* Definitions *******************
// Output operator definition
extern inline
-ostream& operator<<(ostream& out, const InfixOperatorExprAST& obj)
+ostream& operator<<(ostream& out, const PersistentTable& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const PersistentTableEntry& obj)
{
obj.print(out);
out << flush;
return out;
}
-#endif //INFIXOPERATOREXPRAST_H
+#endif //PersistentTable_H
diff --git a/src/mem/ruby/system/SConscript b/src/mem/ruby/system/SConscript
index 1d8b1e2df..4ca1af114 100644
--- a/src/mem/ruby/system/SConscript
+++ b/src/mem/ruby/system/SConscript
@@ -35,8 +35,10 @@ if not env['RUBY']:
Source('DMASequencer.cc')
Source('DirectoryMemory.cc')
+Source('CacheMemory.cc')
Source('MemoryControl.cc')
Source('MemoryNode.cc')
+Source('PersistentTable.cc')
Source('RubyPort.cc')
Source('Sequencer.cc', Werror=False)
Source('System.cc')
diff --git a/src/mem/ruby/system/Sequencer.hh b/src/mem/ruby/system/Sequencer.hh
index 231df01bb..ce53dd8d7 100644
--- a/src/mem/ruby/system/Sequencer.hh
+++ b/src/mem/ruby/system/Sequencer.hh
@@ -63,6 +63,8 @@ struct SequencerRequest {
{}
};
+std::ostream& operator<<(std::ostream& out, const SequencerRequest& obj);
+
class Sequencer : public Consumer, public RubyPort {
public:
// Constructors
diff --git a/src/mem/ruby/system/System.hh b/src/mem/ruby/system/System.hh
index 38ef09177..1d36de878 100644
--- a/src/mem/ruby/system/System.hh
+++ b/src/mem/ruby/system/System.hh
@@ -107,7 +107,10 @@ public:
if (m_ports.count(name) != 1){
cerr << "Port " << name << " has " << m_ports.count(name) << " instances" << endl;
}
- assert(m_ports.count(name) == 1); m_ports[name]->registerHitCallback(hit_callback); return m_ports[name]; }
+ assert(m_ports.count(name) == 1);
+ m_ports[name]->registerHitCallback(hit_callback);
+ return m_ports[name];
+ }
static Network* getNetwork() { assert(m_network_ptr != NULL); return m_network_ptr; }
static Topology* getTopology(const string & name) { assert(m_topologies.count(name) == 1); return m_topologies[name]; }
static CacheMemory* getCache(const string & name) { assert(m_caches.count(name) == 1); return m_caches[name]; }
diff --git a/src/mem/rubymem.cc b/src/mem/rubymem.cc
index 4d9f8051f..74a6e390e 100644
--- a/src/mem/rubymem.cc
+++ b/src/mem/rubymem.cc
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2001-2005 The Regents of The University of Michigan
+ * Copyright (c) 2009 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,6 +27,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Daniel Sanchez
+ * Brad Beckmann
*/
#include <iostream>
@@ -35,6 +37,7 @@
#include "base/output.hh"
#include "base/str.hh"
#include "base/types.hh"
+#include "config/the_isa.hh"
#include "mem/ruby/common/Debug.hh"
#include "mem/ruby/libruby.hh"
#include "mem/ruby/system/RubyPort.hh"
@@ -55,13 +58,23 @@ RubyMemory::RubyMemory(const Params *p)
ruby_clock = p->clock;
ruby_phase = p->phase;
+ ports_per_cpu = p->ports_per_core;
+
+ DPRINTF(Ruby, "creating Ruby Memory from file %s\n",
+ p->config_file.c_str());
+
ifstream config(p->config_file.c_str());
+ if (config.good() == false) {
+ fatal("Did not successfully open %s.\n", p->config_file.c_str());
+ }
+
vector<RubyObjConf> sys_conf;
while (!config.eof()) {
- char buffer[4096];
+ char buffer[65536];
config.getline(buffer, sizeof(buffer));
string line = buffer;
+ DPRINTF(Ruby, "%s %d\n", line, line.empty());
if (line.empty())
continue;
vector<string> tokens;
@@ -80,11 +93,27 @@ RubyMemory::RubyMemory(const Params *p)
RubySystem::create(sys_conf);
+ //
+ // Create the necessary ruby_ports to connect to the sequencers.
+ // This code should be fixed when the configuration systems are unified
+ // and the ruby configuration text files no longer exist. Also,
+ // it would be great to remove the single ruby_hit_callback func with
+ // separate pointers to particular ports to rubymem. However, functional
+ // access currently prevent the improvement.
+ //
for (int i = 0; i < params()->num_cpus; i++) {
RubyPort *p = RubySystem::getPort(csprintf("Sequencer_%d", i),
ruby_hit_callback);
ruby_ports.push_back(p);
}
+
+ for (int i = 0; i < params()->num_dmas; i++) {
+ RubyPort *p = RubySystem::getPort(csprintf("DMASequencer_%d", i),
+ ruby_hit_callback);
+ ruby_dma_ports.push_back(p);
+ }
+
+ pio_port = NULL;
}
void
@@ -105,7 +134,6 @@ RubyMemory::init()
//g_debug_ptr->setDebugTime(1);
//g_debug_ptr->setDebugOutputFile("ruby.debug");
-
g_system_ptr->clearStats();
if (ports.size() == 0) {
@@ -117,9 +145,18 @@ RubyMemory::init()
(*pi)->sendStatusChange(Port::RangeChange);
}
+ for (PortIterator pi = dma_ports.begin(); pi != dma_ports.end(); ++pi) {
+ if (*pi)
+ (*pi)->sendStatusChange(Port::RangeChange);
+ }
+
+ if (pio_port != NULL) {
+ pio_port->sendStatusChange(Port::RangeChange);
+ }
+
//Print stats at exit
- RubyExitCallback* rc = new RubyExitCallback(this);
- registerExitCallback(rc);
+ rubyExitCB = new RubyExitCallback(this);
+ registerExitCallback(rubyExitCB);
//Sched RubyEvent, automatically reschedules to advance ruby cycles
rubyTickEvent = new RubyEvent(this);
@@ -137,37 +174,57 @@ RubyMemory::tick()
RubyMemory::~RubyMemory()
{
-}
-
-void
-RubyMemory::hitCallback(PacketPtr pkt, Port *port)
-{
- DPRINTF(MemoryAccess, "Hit callback\n");
-
- bool needsResponse = pkt->needsResponse();
- doAtomicAccess(pkt);
-
- // turn packet around to go back to requester if response expected
- if (needsResponse) {
- // recvAtomic() should already have turned packet into
- // atomic response
- assert(pkt->isResponse());
- DPRINTF(MemoryAccess, "Sending packet back over port\n");
- port->sendTiming(pkt);
- } else {
- delete pkt;
- }
- DPRINTF(MemoryAccess, "Hit callback done!\n");
+ delete g_system_ptr;
}
Port *
RubyMemory::getPort(const std::string &if_name, int idx)
{
+ DPRINTF(Ruby, "getting port %d %s\n", idx, if_name);
+ DPRINTF(Ruby,
+ "number of ruby ports %d and dma ports %d\n",
+ ruby_ports.size(),
+ ruby_dma_ports.size());
+
+ //
+ // By default, getPort will be passed an idx of -1. Of course this is an
+ // invalid ruby port index and must be a modified
+ //
+ if (idx == -1) {
+ idx = 0;
+ }
+
// Accept request for "functional" port for backwards compatibility
// with places where this function is called from C++. I'd prefer
// to move all these into Python someday.
if (if_name == "functional") {
- return new Port(csprintf("%s-functional", name()), this);
+ assert(idx < ruby_ports.size());
+ return new Port(csprintf("%s-functional", name()),
+ this,
+ ruby_ports[idx]);
+ }
+
+ //
+ // if dma port request, allocate the appropriate prot
+ //
+ if (if_name == "dma_port") {
+ assert(idx < ruby_dma_ports.size());
+ RubyMemory::Port* dma_port =
+ new Port(csprintf("%s-dma_port%d", name(), idx),
+ this,
+ ruby_dma_ports[idx]);
+ dma_ports.push_back(dma_port);
+ return dma_port;
+ }
+
+ //
+ // if pio port, ensure that there is only one
+ //
+ if (if_name == "pio_port") {
+ assert(pio_port == NULL);
+ pio_port =
+ new RubyMemory::Port("ruby_pio_port", this, NULL);
+ return pio_port;
}
if (if_name != "port") {
@@ -182,30 +239,68 @@ RubyMemory::getPort(const std::string &if_name, int idx)
panic("RubyMemory::getPort: port %d already assigned", idx);
}
- Port *port = new Port(csprintf("%s-port%d", name(), idx), this);
+ //
+ // Currently this code assumes that each cpu has both a
+ // icache and dcache port and therefore divides by ports per cpu. This will
+ // be fixed once we unify the configuration systems and Ruby sequencers
+ // directly support M5 ports.
+ //
+ assert(idx/ports_per_cpu < ruby_ports.size());
+ Port *port = new Port(csprintf("%s-port%d", name(), idx),
+ this,
+ ruby_ports[idx/ports_per_cpu]);
ports[idx] = port;
return port;
}
-RubyMemory::Port::Port(const std::string &_name, RubyMemory *_memory)
+RubyMemory::Port::Port(const std::string &_name,
+ RubyMemory *_memory,
+ RubyPort *_port)
: PhysicalMemory::MemoryPort::MemoryPort(_name, _memory)
{
+ DPRINTF(Ruby, "creating port to ruby memory %s\n", _name);
ruby_mem = _memory;
+ ruby_port = _port;
}
bool
RubyMemory::Port::recvTiming(PacketPtr pkt)
{
- DPRINTF(MemoryAccess, "Timing access caught\n");
+ DPRINTF(MemoryAccess,
+ "Timing access caught for address %#x\n",
+ pkt->getAddr());
//dsm: based on SimpleTimingPort::recvTiming(pkt);
- // If the device is only a slave, it should only be sending
- // responses, which should never get nacked. There used to be
- // code to hanldle nacks here, but I'm pretty sure it didn't work
- // correctly with the drain code, so that would need to be fixed
- // if we ever added it back.
+ //
+ // In FS mode, ruby memory will receive pio responses from devices and
+ // it must forward these responses back to the particular CPU.
+ //
+ if (pkt->isResponse() != false && isPioAddress(pkt->getAddr()) != false) {
+ DPRINTF(MemoryAccess,
+ "Pio Response callback %#x\n",
+ pkt->getAddr());
+ RubyMemory::SenderState *senderState =
+ safe_cast<RubyMemory::SenderState *>(pkt->senderState);
+ RubyMemory::Port *port = senderState->port;
+
+ // pop the sender state from the packet
+ pkt->senderState = senderState->saved;
+ delete senderState;
+
+ port->sendTiming(pkt);
+
+ return true;
+ }
+
+ //
+ // After checking for pio responses, the remainder of packets
+ // received by ruby should only be M5 requests, which should never
+ // get nacked. There used to be code to hanldle nacks here, but
+ // I'm pretty sure it didn't work correctly with the drain code,
+ // so that would need to be fixed if we ever added it back.
+ //
assert(pkt->isRequest());
if (pkt->memInhibitAsserted()) {
@@ -219,6 +314,18 @@ RubyMemory::Port::recvTiming(PacketPtr pkt)
// Save the port in the sender state object
pkt->senderState = new SenderState(this, pkt->senderState);
+ //
+ // Check for pio requests and directly send them to the dedicated
+ // pio_port.
+ //
+ if (isPioAddress(pkt->getAddr()) != false) {
+ return ruby_mem->pio_port->sendTiming(pkt);
+ }
+
+ //
+ // For DMA and CPU requests, translate them to ruby requests before
+ // sending them to our assigned ruby port.
+ //
RubyRequestType type = RubyRequestType_NULL;
Addr pc = 0;
if (pkt->isRead()) {
@@ -239,7 +346,6 @@ RubyMemory::Port::recvTiming(PacketPtr pkt)
RubyAccessMode_Supervisor);
// Submit the ruby request
- RubyPort *ruby_port = ruby_mem->ruby_ports[pkt->req->contextId()];
int64_t req_id = ruby_port->makeRequest(ruby_request);
if (req_id == -1) {
RubyMemory::SenderState *senderState =
@@ -260,6 +366,12 @@ RubyMemory::Port::recvTiming(PacketPtr pkt)
void
ruby_hit_callback(int64_t req_id)
{
+ //
+ // Note: This single fuction can be called by cpu and dma ports,
+ // as well as the functional port. The functional port prevents
+ // us from replacing this single function with separate port
+ // functions.
+ //
typedef map<int64_t, PacketPtr> map_t;
map_t &prm = RubyMemory::pending_requests;
@@ -278,13 +390,58 @@ ruby_hit_callback(int64_t req_id)
pkt->senderState = senderState->saved;
delete senderState;
- port->ruby_mem->hitCallback(pkt, port);
+ port->hitCallback(pkt);
}
void
+RubyMemory::Port::hitCallback(PacketPtr pkt)
+{
+
+ bool needsResponse = pkt->needsResponse();
+
+ DPRINTF(MemoryAccess, "Hit callback needs response %d\n",
+ needsResponse);
+
+ ruby_mem->doAtomicAccess(pkt);
+
+ // turn packet around to go back to requester if response expected
+ if (needsResponse) {
+ // recvAtomic() should already have turned packet into
+ // atomic response
+ assert(pkt->isResponse());
+ DPRINTF(MemoryAccess, "Sending packet back over port\n");
+ sendTiming(pkt);
+ } else {
+ delete pkt;
+ }
+ DPRINTF(MemoryAccess, "Hit callback done!\n");
+}
+
+bool
RubyMemory::Port::sendTiming(PacketPtr pkt)
{
schedSendTiming(pkt, curTick + 1); //minimum latency, must be > 0
+ return true;
+}
+
+bool
+RubyMemory::Port::isPioAddress(Addr addr)
+{
+ AddrRangeList pioAddrList;
+ bool snoop = false;
+ if (ruby_mem->pio_port == NULL) {
+ return false;
+ }
+
+ ruby_mem->pio_port->getPeerAddressRanges(pioAddrList, snoop);
+ for(AddrRangeIter iter = pioAddrList.begin(); iter != pioAddrList.end(); iter++) {
+ if (addr >= iter->start && addr <= iter->end) {
+ DPRINTF(MemoryAccess, "Pio request found in %#llx - %#llx range\n",
+ iter->start, iter->end);
+ return true;
+ }
+ }
+ return false;
}
void RubyMemory::printConfigStats()
@@ -311,6 +468,17 @@ void RubyMemory::printConfig(std::ostream & out) const {
//g_system_ptr->printConfig(out);
}
+void RubyMemory::serialize(ostream &os)
+{
+ PhysicalMemory::serialize(os);
+}
+
+void RubyMemory::unserialize(Checkpoint *cp, const string &section)
+{
+ DPRINTF(Config, "Ruby memory being restored\n");
+ reschedule(rubyTickEvent, curTick + ruby_clock + ruby_phase);
+ PhysicalMemory::unserialize(cp, section);
+}
//Python-interface code
RubyMemory *
diff --git a/src/mem/rubymem.hh b/src/mem/rubymem.hh
index e33418a42..2672dcb77 100644
--- a/src/mem/rubymem.hh
+++ b/src/mem/rubymem.hh
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2001-2005 The Regents of The University of Michigan
+ * Copyright (c) 2009 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -39,23 +40,34 @@
#include "mem/physical.hh"
#include "mem/ruby/system/RubyPort.hh"
#include "params/RubyMemory.hh"
+#include "mem/port.hh"
+
+class RubyExitCallback;
class RubyMemory : public PhysicalMemory
{
public:
std::vector<RubyPort *> ruby_ports;
+ std::vector<RubyPort *> ruby_dma_ports;
class Port : public MemoryPort
{
friend void ruby_hit_callback(int64_t req_id);
RubyMemory *ruby_mem;
+ RubyPort *ruby_port;
public:
- Port(const std::string &_name, RubyMemory *_memory);
- void sendTiming(PacketPtr pkt);
+ Port(const std::string &_name,
+ RubyMemory *_memory,
+ RubyPort *_port);
+ bool sendTiming(PacketPtr pkt);
+ void hitCallback(PacketPtr pkt);
protected:
virtual bool recvTiming(PacketPtr pkt);
+
+ private:
+ bool isPioAddress(Addr addr);
};
class RubyEvent : public Event
@@ -108,8 +120,6 @@ class RubyMemory : public PhysicalMemory
//options change & M5 determines the
//stats file to use
- void hitCallback(PacketPtr pkt, Port *port);
-
void printStats(std::ostream & out) const;
void clearStats();
void printConfig(std::ostream & out) const;
@@ -119,9 +129,19 @@ class RubyMemory : public PhysicalMemory
private:
Tick ruby_clock;
Tick ruby_phase;
+ RubyExitCallback* rubyExitCB;
+ int ports_per_cpu;
public:
static std::map<int64_t, PacketPtr> pending_requests;
+ RubyMemory::Port* pio_port;
+
+ protected:
+ std::vector<MemoryPort*> dma_ports;
+
+ public:
+ virtual void serialize(std::ostream &os);
+ virtual void unserialize(Checkpoint *cp, const std::string &section);
};
void ruby_hit_callback(int64_t);
diff --git a/src/mem/slicc/SConscript b/src/mem/slicc/SConscript
deleted file mode 100644
index e26ceb979..000000000
--- a/src/mem/slicc/SConscript
+++ /dev/null
@@ -1,129 +0,0 @@
-# -*- mode:python -*-
-
-# Copyright (c) 2009 The Hewlett-Packard Development Company
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met: redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer;
-# redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution;
-# neither the name of the copyright holders nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# Authors: Nathan Binkert
-
-import os
-import re
-import string
-import sys
-
-from os.path import basename, dirname, exists, expanduser, isdir, isfile
-from os.path import join as joinpath
-
-import SCons
-
-Import('*')
-
-if not env['RUBY']:
- Return()
-
-common_dir = Dir('../gems_common')
-
-#
-# Build SLICC
-#
-slicc_env = env.Clone()
-slicc_env['CPPDEFINES'] = ''
-slicc_env['CPPPATH'] = Dir('../..')
-slicc_env.Append(CCFLAGS=['-g', '-O0'])
-slicc_env.Append(CPPDEFINES=['DEBUG', 'TRACING_ON=1'])
-slicc_env['LIBS'] = ''
-slicc_env['LIBPATH'] = ''
-all_slicc_sources = []
-def SliccSource(filename):
- if filename.endswith('.ll') or filename.endswith('.yy'):
- slicc_env.CXXFile(filename)
- filename = filename[:-2] + "cc"
- x = slicc_env.StaticObject(filename)
- all_slicc_sources.append(x)
- return x
-
-# BE CAREFUL WITH THE ORDER OF FILENAMES HERE. SLICC IS VERY FRAGILE
-# BECAUSE IT VIOLATES ESTABLISHED RULES ABOUT HOW YOU'RE ALLOWED TO
-# CREATE STATIC OBJECTS. (SLICC HAS DEPENDENCIES DURING STATIC OBJECT
-# CONSTRUCTION ACROSS FILES. THAT'S A NO-NO.) WITH THIS FILE ORDER,
-# WE GET LUCKY AND OBJECTS GET CONSTRUCTED IN THE RIGHT ORDER.
-SliccSource('parser/parser.yy')
-SliccSource('parser/lexer.ll')
-SliccSource('main.cc')
-SliccSource('symbols/Func.cc')
-SliccSource('symbols/StateMachine.cc')
-SliccSource('symbols/Symbol.cc')
-SliccSource('symbols/SymbolTable.cc')
-SliccSource('symbols/Transition.cc')
-SliccSource('symbols/Type.cc')
-SliccSource('symbols/Var.cc')
-SliccSource('generator/fileio.cc')
-SliccSource('generator/html_gen.cc')
-SliccSource('generator/mif_gen.cc')
-SliccSource('ast/AST.cc')
-SliccSource('ast/ActionDeclAST.cc')
-SliccSource('ast/AssignStatementAST.cc')
-SliccSource('ast/CheckAllocateStatementAST.cc')
-SliccSource('ast/CheckStopSlotsStatementAST.cc')
-SliccSource('ast/ChipComponentAccessAST.cc')
-SliccSource('ast/CopyHeadStatementAST.cc')
-SliccSource('ast/DeclAST.cc')
-SliccSource('ast/DeclListAST.cc')
-SliccSource('ast/EnqueueStatementAST.cc')
-SliccSource('ast/EnumDeclAST.cc')
-SliccSource('ast/EnumExprAST.cc')
-SliccSource('ast/ExprAST.cc')
-SliccSource('ast/ExprStatementAST.cc')
-SliccSource('ast/FormalParamAST.cc')
-SliccSource('ast/FuncCallExprAST.cc')
-SliccSource('ast/FuncDeclAST.cc')
-SliccSource('ast/IfStatementAST.cc')
-SliccSource('ast/InPortDeclAST.cc')
-SliccSource('ast/InfixOperatorExprAST.cc')
-SliccSource('ast/LiteralExprAST.cc')
-SliccSource('ast/Location.cc')
-SliccSource('ast/MachineAST.cc')
-SliccSource('ast/MemberExprAST.cc')
-SliccSource('ast/MethodCallExprAST.cc')
-SliccSource('ast/NewExprAST.cc')
-SliccSource('ast/ObjDeclAST.cc')
-SliccSource('ast/OutPortDeclAST.cc')
-SliccSource('ast/PairAST.cc')
-SliccSource('ast/PairListAST.cc')
-SliccSource('ast/PeekStatementAST.cc')
-SliccSource('ast/ReturnStatementAST.cc')
-SliccSource('ast/StatementAST.cc')
-SliccSource('ast/StatementListAST.cc')
-SliccSource('ast/TransitionDeclAST.cc')
-SliccSource('ast/TypeAST.cc')
-SliccSource('ast/TypeDeclAST.cc')
-SliccSource('ast/TypeFieldAST.cc')
-SliccSource('ast/TypeFieldEnumAST.cc')
-SliccSource('ast/TypeFieldMemberAST.cc')
-SliccSource('ast/TypeFieldMethodAST.cc')
-SliccSource('ast/VarExprAST.cc')
-
-slicc_bin = File('slicc')
-slicc_env.Program(slicc_bin, all_slicc_sources + [ common_dir.File('util.o') ])
diff --git a/src/mem/slicc/__init__.py b/src/mem/slicc/__init__.py
new file mode 100644
index 000000000..8ce04e77d
--- /dev/null
+++ b/src/mem/slicc/__init__.py
@@ -0,0 +1,25 @@
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/mem/slicc/ast/AST.hh b/src/mem/slicc/ast/AST.hh
deleted file mode 100644
index 33c9b84ed..000000000
--- a/src/mem/slicc/ast/AST.hh
+++ /dev/null
@@ -1,94 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * AST.hh
- *
- * Description:
- *
- * $Id$
- *
- */
-
-#ifndef AST_H
-#define AST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/gems_common/Vector.hh"
-#include "mem/gems_common/Map.hh"
-#include "mem/slicc/ast/Location.hh"
-#include "mem/slicc/symbols/SymbolTable.hh"
-
-class AST {
-public:
- // Constructors
- AST(Map<string, string> pairs) { m_pairs = pairs; };
- AST() {};
-
- // Destructor
- virtual ~AST() {};
-
- // Public Methods
- virtual void print(ostream& out) const = 0;
- void error(string err_msg) const { m_location.error(err_msg); };
- string embedError(string err_msg) const { return m_location.embedError(err_msg); };
- void warning(string err_msg) const { m_location.warning(err_msg); };
-
- const Location& getLocation() const { return m_location; };
-
- const Map<string, string>& getPairs() const { return m_pairs; };
- Map<string, string>& getPairs() { return m_pairs; };
-
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- // AST(const AST& obj);
- // AST& operator=(const AST& obj);
-
- // Data Members (m_ prefix)
- Location m_location;
- Map<string, string> m_pairs;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const AST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const AST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //AST_H
diff --git a/src/mem/slicc/ast/AST.py b/src/mem/slicc/ast/AST.py
new file mode 100644
index 000000000..5b1b124cd
--- /dev/null
+++ b/src/mem/slicc/ast/AST.py
@@ -0,0 +1,63 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.util import code_formatter
+
+from slicc.util import PairContainer, Location
+
+class AST(PairContainer):
+ def __init__(self, slicc, pairs=None):
+ self.slicc = slicc
+ self.location = Location(slicc.current_file, slicc.lexer.lineno)
+ self.pairs = {}
+ if pairs:
+ self.pairs.update(getattr(pairs, "pairs", pairs))
+
+ @property
+ def symtab(self):
+ return self.slicc.symtab
+
+ @property
+ def state_machine(self):
+ return self.slicc.symtab.state_machine
+
+ def warning(self, message, *args):
+ self.location.warning(message, *args)
+
+ def error(self, message, *args):
+ self.location.error(message, *args)
+
+ def embedError(self, message, *args):
+ if args:
+ message = message % args
+ code = code_formatter()
+ code('''
+cerr << "Runtime Error at ${{self.location}}, Ruby Time: " << g_eventQueue_ptr->getTime() << ": "<< $message << ", PID: " << getpid() << endl;
+char c; cerr << "press return to continue." << endl; cin.get(c); abort();
+''')
+
+ return code
diff --git a/src/mem/slicc/ast/ASTs.hh b/src/mem/slicc/ast/ASTs.hh
deleted file mode 100644
index 3363fbb09..000000000
--- a/src/mem/slicc/ast/ASTs.hh
+++ /dev/null
@@ -1,91 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- *
- */
-
-#ifndef ASTs_H
-#define ASTs_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/main.hh"
-#include "mem/slicc/symbols/StateMachine.hh"
-#include "mem/slicc/ast/AST.hh"
-
-#include "mem/slicc/ast/MachineAST.hh"
-
-#include "mem/slicc/ast/TypeAST.hh"
-#include "mem/slicc/ast/FormalParamAST.hh"
-
-#include "mem/slicc/ast/DeclListAST.hh"
-#include "mem/slicc/ast/DeclAST.hh"
-#include "mem/slicc/ast/ActionDeclAST.hh"
-#include "mem/slicc/ast/InPortDeclAST.hh"
-#include "mem/slicc/ast/OutPortDeclAST.hh"
-#include "mem/slicc/ast/TransitionDeclAST.hh"
-#include "mem/slicc/ast/EnumDeclAST.hh"
-#include "mem/slicc/ast/TypeDeclAST.hh"
-#include "mem/slicc/ast/ObjDeclAST.hh"
-#include "mem/slicc/ast/FuncDeclAST.hh"
-
-#include "mem/slicc/ast/TypeFieldAST.hh"
-#include "mem/slicc/ast/TypeFieldMethodAST.hh"
-#include "mem/slicc/ast/TypeFieldMemberAST.hh"
-#include "mem/slicc/ast/TypeFieldEnumAST.hh"
-
-#include "mem/slicc/ast/PairAST.hh"
-#include "mem/slicc/ast/PairListAST.hh"
-
-#include "mem/slicc/ast/ExprAST.hh"
-#include "mem/slicc/ast/VarExprAST.hh"
-#include "mem/slicc/ast/EnumExprAST.hh"
-#include "mem/slicc/ast/LiteralExprAST.hh"
-#include "mem/slicc/ast/MemberExprAST.hh"
-#include "mem/slicc/ast/InfixOperatorExprAST.hh"
-#include "mem/slicc/ast/FuncCallExprAST.hh"
-#include "mem/slicc/ast/MethodCallExprAST.hh"
-#include "mem/slicc/ast/NewExprAST.hh"
-
-#include "mem/slicc/ast/ChipComponentAccessAST.hh"
-
-#include "mem/slicc/ast/StatementListAST.hh"
-#include "mem/slicc/ast/StatementAST.hh"
-#include "mem/slicc/ast/ExprStatementAST.hh"
-#include "mem/slicc/ast/AssignStatementAST.hh"
-#include "mem/slicc/ast/EnqueueStatementAST.hh"
-#include "mem/slicc/ast/IfStatementAST.hh"
-#include "mem/slicc/ast/PeekStatementAST.hh"
-#include "mem/slicc/ast/CopyHeadStatementAST.hh"
-#include "mem/slicc/ast/CheckAllocateStatementAST.hh"
-#include "mem/slicc/ast/CheckStopSlotsStatementAST.hh"
-#include "mem/slicc/ast/ReturnStatementAST.hh"
-
-#endif //ASTs_H
diff --git a/src/mem/slicc/ast/ActionDeclAST.cc b/src/mem/slicc/ast/ActionDeclAST.cc
deleted file mode 100644
index e46412ff7..000000000
--- a/src/mem/slicc/ast/ActionDeclAST.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * ActionDeclAST.C
- *
- * Description: See ActionDeclAST.hh
- *
- * $Id$
- *
- */
-
-
-#include "mem/slicc/ast/ActionDeclAST.hh"
-#include "mem/slicc/symbols/Action.hh"
-#include "mem/slicc/ast/StatementListAST.hh"
-
-ActionDeclAST::ActionDeclAST(string* ident_ptr,
- PairListAST* pairs_ptr,
- StatementListAST* statement_list_ptr)
- : DeclAST(pairs_ptr)
-{
- m_ident_ptr = ident_ptr;
- m_statement_list_ptr = statement_list_ptr;
-}
-
-ActionDeclAST::~ActionDeclAST()
-{
- delete m_ident_ptr;
- delete m_statement_list_ptr;
-}
-
-void ActionDeclAST::generate()
-{
- Map<Var*, string> resource_list;
- if (m_statement_list_ptr != NULL) {
- string code;
-
- // Add new local vars
- g_sym_table.pushFrame();
-
- Type* type_ptr = g_sym_table.getType("Address");
-
- if (type_ptr == NULL) {
- error("Type 'Address' not declared.");
- }
-
- g_sym_table.newSym(new Var("address", getLocation(), type_ptr, "addr", getPairs()));
-
- // Don't allows returns in actions
- m_statement_list_ptr->generate(code, NULL);
-
- getPairs().add("c_code", code);
-
- m_statement_list_ptr->findResources(resource_list);
-
- g_sym_table.popFrame();
- }
-
- StateMachine* machine_ptr = g_sym_table.getStateMachine();
- if (machine_ptr == NULL) {
- error("Action declaration not part of a machine.");
- } else {
- machine_ptr->addAction(new Action(*m_ident_ptr, resource_list, getLocation(), getPairs()));
- }
-
-}
-
-void ActionDeclAST::print(ostream& out) const
-{
- out << "[ActionDecl: " << *m_ident_ptr << "]";
-}
diff --git a/src/mem/slicc/ast/ActionDeclAST.hh b/src/mem/slicc/ast/ActionDeclAST.hh
deleted file mode 100644
index 4970ee254..000000000
--- a/src/mem/slicc/ast/ActionDeclAST.hh
+++ /dev/null
@@ -1,86 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * ActionDeclAST.hh
- *
- * Description:
- *
- * $Id: ActionDeclAST.hh,v 3.2 2003/07/10 18:08:06 milo Exp $
- *
- */
-
-#ifndef ActionDeclAST_H
-#define ActionDeclAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/DeclAST.hh"
-
-class StatementListAST;
-
-class ActionDeclAST : public DeclAST {
-public:
- // Constructors
- ActionDeclAST(string* ident_ptr,
- PairListAST* pairs_ptr,
- StatementListAST* statement_list_ptr);
-
- // Destructor
- ~ActionDeclAST();
-
- // Public Methods
- void generate();
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- ActionDeclAST(const ActionDeclAST& obj);
- ActionDeclAST& operator=(const ActionDeclAST& obj);
-
- // Data Members (m_ prefix)
- string* m_ident_ptr;
- StatementListAST* m_statement_list_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const ActionDeclAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const ActionDeclAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //ActionDeclAST_H
diff --git a/src/mem/slicc/ast/ActionDeclAST.py b/src/mem/slicc/ast/ActionDeclAST.py
new file mode 100644
index 000000000..18bf443b9
--- /dev/null
+++ b/src/mem/slicc/ast/ActionDeclAST.py
@@ -0,0 +1,72 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.util import code_formatter
+
+from slicc.ast.DeclAST import DeclAST
+from slicc.symbols import Action, Type, Var
+
+class ActionDeclAST(DeclAST):
+ def __init__(self, slicc, ident, pairs, statement_list):
+ super(ActionDeclAST, self).__init__(slicc, pairs)
+ self.ident = ident
+ self.statement_list = statement_list
+
+ def __repr__(self):
+ return "[ActionDecl: %r]" % (self.ident)
+
+ def generate(self):
+ resources = {}
+ if self.statement_list:
+ # Add new local vars
+ self.symtab.pushFrame()
+
+ addr_type = self.symtab.find("Address", Type)
+
+ if addr_type is None:
+ self.error("Type 'Address' not declared.")
+
+ var = Var(self.symtab, "address", self.location, addr_type,
+ "addr", self.pairs)
+ self.symtab.newSymbol(var)
+
+ # Do not allows returns in actions
+ code = code_formatter()
+ self.statement_list.generate(code, None)
+ self.pairs["c_code"] = str(code)
+
+ self.statement_list.findResources(resources)
+
+ self.symtab.popFrame()
+
+ machine = self.symtab.state_machine
+ if machine is None:
+ self.error("Action declaration not part of a machine.")
+
+ action = Action(self.symtab, self.ident, resources, self.location,
+ self.pairs)
+ machine.addAction(action)
diff --git a/src/mem/slicc/ast/AssignStatementAST.cc b/src/mem/slicc/ast/AssignStatementAST.cc
deleted file mode 100644
index 8cf42aa63..000000000
--- a/src/mem/slicc/ast/AssignStatementAST.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * AssignStatementAST.C
- *
- * Description: See AssignStatementAST.hh
- *
- * $Id: AssignStatementAST.C,v 3.2 2003/08/01 18:38:19 beckmann Exp $
- *
- */
-
-#include "mem/slicc/ast/AssignStatementAST.hh"
-
-AssignStatementAST::AssignStatementAST(ExprAST* lvalue_ptr, ExprAST* rvalue_ptr)
- : StatementAST()
-{
- m_lvalue_ptr = lvalue_ptr;
- m_rvalue_ptr = rvalue_ptr;
-}
-
-AssignStatementAST::~AssignStatementAST()
-{
- delete m_lvalue_ptr;
- delete m_rvalue_ptr;
-}
-
-void AssignStatementAST::generate(string& code, Type* return_type_ptr) const
-{
- code += indent_str();
- Type* lvalue_type_ptr = m_lvalue_ptr->generate(code);
- code += " = ";
- Type* rvalue_type_ptr = m_rvalue_ptr->generate(code);
- code += ";\n";
-
- if (lvalue_type_ptr != rvalue_type_ptr) {
- // FIXME - beckmann
- // the following if statement is a hack to allow NetDest objects to be assigned to Sets
- // this allows for the previous NetworkMessage Destiantion 'Set class' to migrate to the
- // new NetworkMessage Destiantion 'NetDest class'
- if (lvalue_type_ptr->toString() != "NetDest" && rvalue_type_ptr->toString() != "Set") {
- error("Assignment type mismatch '" + lvalue_type_ptr->toString() + "' and '" + rvalue_type_ptr->toString() + "'");
- }
- }
-}
-
-void AssignStatementAST::print(ostream& out) const
-{
- out << "[AssignStatementAST: " << *m_lvalue_ptr << " := " << *m_rvalue_ptr << "]";
-}
diff --git a/src/mem/slicc/ast/AssignStatementAST.hh b/src/mem/slicc/ast/AssignStatementAST.hh
deleted file mode 100644
index 2c19da831..000000000
--- a/src/mem/slicc/ast/AssignStatementAST.hh
+++ /dev/null
@@ -1,85 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * AssignStatementAST.hh
- *
- * Description:
- *
- * $Id: AssignStatementAST.hh,v 3.2 2001/12/12 01:00:09 milo Exp $
- *
- */
-
-#ifndef ASSIGNSTATEMENTAST_H
-#define ASSIGNSTATEMENTAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/StatementAST.hh"
-#include "mem/slicc/ast/ExprAST.hh"
-
-
-
-class AssignStatementAST : public StatementAST {
-public:
- // Constructors
- AssignStatementAST(ExprAST* lvalue_ptr, ExprAST* rvalue_ptr);
-
- // Destructor
- ~AssignStatementAST();
-
- // Public Methods
- void generate(string& code, Type* return_type_ptr) const;
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- AssignStatementAST(const AssignStatementAST& obj);
- AssignStatementAST& operator=(const AssignStatementAST& obj);
-
- // Data Members (m_ prefix)
- ExprAST* m_lvalue_ptr;
- ExprAST* m_rvalue_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const AssignStatementAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const AssignStatementAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //ASSIGNSTATEMENTAST_H
diff --git a/src/mem/slicc/ast/AssignStatementAST.py b/src/mem/slicc/ast/AssignStatementAST.py
new file mode 100644
index 000000000..f8e77b03b
--- /dev/null
+++ b/src/mem/slicc/ast/AssignStatementAST.py
@@ -0,0 +1,59 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.util import code_formatter
+
+from slicc.ast.StatementAST import StatementAST
+
+class AssignStatementAST(StatementAST):
+ def __init__(self, slicc, lvalue, rvalue):
+ super(AssignStatementAST, self).__init__(slicc)
+ self.lvalue = lvalue
+ self.rvalue = rvalue
+
+ def __repr__(self):
+ return "[AssignStatementAST: %r := %r]" % (self.lvalue, self.rvalue)
+
+ def generate(self, code, return_type):
+ lcode = code_formatter()
+ rcode = code_formatter()
+
+ ltype = self.lvalue.generate(lcode)
+ rtype = self.rvalue.generate(rcode)
+
+ code("$lcode = $rcode;")
+
+ if ltype != rtype:
+ # FIXME - beckmann
+ # the following if statement is a hack to allow NetDest
+ # objects to be assigned to Sets this allows for the
+ # previous NetworkMessage Destiantion 'Set class' to
+ # migrate to the new NetworkMessage Destiantion 'NetDest
+ # class'
+ if str(ltype) != "NetDest" and str(rtype) != "Set":
+ self.error("Assignment type mismatch '%s' and '%s'",
+ ltype, rtype)
diff --git a/src/mem/slicc/ast/CheckAllocateStatementAST.cc b/src/mem/slicc/ast/CheckAllocateStatementAST.cc
deleted file mode 100644
index 1f498efe2..000000000
--- a/src/mem/slicc/ast/CheckAllocateStatementAST.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- *
- */
-
-#include "mem/slicc/ast/CheckAllocateStatementAST.hh"
-#include "mem/slicc/symbols/SymbolTable.hh"
-#include "mem/slicc/ast/VarExprAST.hh"
-#include "mem/gems_common/util.hh"
-
-CheckAllocateStatementAST::CheckAllocateStatementAST(VarExprAST* variable)
- : StatementAST()
-{
- m_variable = variable;
-}
-
-CheckAllocateStatementAST::~CheckAllocateStatementAST()
-{
- delete m_variable;
-}
-
-void CheckAllocateStatementAST::generate(string& code, Type* return_type_ptr) const
-{
- // FIXME - check the type of the variable
-
- // Make sure the variable is valid
- m_variable->getVar();
-}
-
-void CheckAllocateStatementAST::findResources(Map<Var*, string>& resource_list) const
-{
- Var* var_ptr = m_variable->getVar();
- int res_count = 0;
- if (resource_list.exist(var_ptr)) {
- res_count = atoi((resource_list.lookup(var_ptr)).c_str());
- }
- resource_list.add(var_ptr, int_to_string(res_count+1));
-}
-
-void CheckAllocateStatementAST::print(ostream& out) const
-{
- out << "[CheckAllocateStatementAst: " << *m_variable << "]";
-}
diff --git a/src/mem/slicc/ast/CheckAllocateStatementAST.py b/src/mem/slicc/ast/CheckAllocateStatementAST.py
new file mode 100644
index 000000000..b96153b0a
--- /dev/null
+++ b/src/mem/slicc/ast/CheckAllocateStatementAST.py
@@ -0,0 +1,47 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.StatementAST import StatementAST
+
+class CheckAllocateStatementAST(StatementAST):
+ def __init__(self, slicc, variable):
+ super(StatementAST, self).__init__(slicc)
+ self.variable = variable
+
+ def __repr__(self):
+ return "[CheckAllocateStatementAst: %r]" % self.variable
+
+ def generate(self, code, return_type):
+ # FIXME - check the type of the variable
+
+ # Make sure the variable is valid
+ self.variable.var
+
+ def findResources(self, resources):
+ var = self.variable.var
+ res_count = int(resources.get(var, 0))
+ resources[var] = str(res_count + 1)
diff --git a/src/mem/slicc/ast/CheckStopSlotsStatementAST.cc b/src/mem/slicc/ast/CheckStopSlotsStatementAST.cc
deleted file mode 100644
index 38dc449d6..000000000
--- a/src/mem/slicc/ast/CheckStopSlotsStatementAST.cc
+++ /dev/null
@@ -1,115 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- *
- */
-
-#include "mem/slicc/ast/CheckStopSlotsStatementAST.hh"
-#include "mem/slicc/symbols/SymbolTable.hh"
-#include "mem/slicc/ast/VarExprAST.hh"
-#include "mem/slicc/ast/PairListAST.hh"
-
-CheckStopSlotsStatementAST::CheckStopSlotsStatementAST(VarExprAST* variable, string* condStr, string* bankStr)
- : StatementAST()
-{
- m_variable = variable;
- m_condStr_ptr = condStr;
- m_bankStr_ptr = bankStr;
-}
-
-CheckStopSlotsStatementAST::~CheckStopSlotsStatementAST()
-{
- delete m_variable;
- delete m_condStr_ptr;
- delete m_bankStr_ptr;
-}
-
-void CheckStopSlotsStatementAST::generate(string& code, Type* return_type_ptr) const
-{
-
- // Make sure the variable is valid
- m_variable->getVar();
-
-}
-
-void CheckStopSlotsStatementAST::findResources(Map<Var*, string>& resource_list) const
-{
- Type* type_ptr;
-
- Var* var_ptr = m_variable->getVar();
- string check_code;
-
- if (*m_condStr_ptr == "((*in_msg_ptr)).m_isOnChipSearch") {
- check_code += " const Response9Msg* in_msg_ptr;\n";
- check_code += " in_msg_ptr = dynamic_cast<const Response9Msg*>(((*(m_chip_ptr->m_L2Cache_responseToL2Cache9_vec[m_version]))).peek());\n";
- check_code += " assert(in_msg_ptr != NULL);\n";
- }
-
- check_code += " if (";
- check_code += *m_condStr_ptr;
- check_code += ") {\n";
-
- check_code += " if (!";
- type_ptr = m_variable->generate(check_code);
- check_code += ".isDisableSPossible((((*(m_chip_ptr->m_DNUCAmover_ptr))).getBankPos(";
- check_code += *m_bankStr_ptr;
- check_code += ")))) {\n";
- if(CHECK_INVALID_RESOURCE_STALLS) {
- check_code += " assert(priority >= ";
- type_ptr = m_variable->generate(check_code);
- check_code += ".getPriority());\n";
- }
- check_code += " return TransitionResult_ResourceStall;\n";
- check_code += " }\n";
- check_code += " } else {\n";
- check_code += " if (!";
- type_ptr = m_variable->generate(check_code);
- check_code += ".isDisableFPossible((((*(m_chip_ptr->m_DNUCAmover_ptr))).getBankPos(";
- check_code += *m_bankStr_ptr;
- check_code += ")))) {\n";
- if(CHECK_INVALID_RESOURCE_STALLS) {
- check_code += " assert(priority >= ";
- type_ptr = m_variable->generate(check_code);
- check_code += ".getPriority());\n";
- }
- check_code += " return TransitionResult_ResourceStall;\n";
- check_code += " }\n";
- check_code += " }\n";
-
- assert(!resource_list.exist(var_ptr));
- resource_list.add(var_ptr, check_code);
-
-}
-
-void CheckStopSlotsStatementAST::print(ostream& out) const
-{
- out << "[CheckStopSlotsStatementAst: " << *m_variable << "]";
-}
diff --git a/src/mem/slicc/ast/CheckStopSlotsStatementAST.hh b/src/mem/slicc/ast/CheckStopSlotsStatementAST.hh
deleted file mode 100644
index 6de068caa..000000000
--- a/src/mem/slicc/ast/CheckStopSlotsStatementAST.hh
+++ /dev/null
@@ -1,85 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- *
- */
-
-#ifndef CHECKSTOPSLOTSSTATEMENTAST_H
-#define CHECKSTOPSLOTSSTATEMENTAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/ExprAST.hh"
-#include "mem/slicc/ast/StatementAST.hh"
-#include "mem/slicc/ast/TypeAST.hh"
-
-class VarExprAST;
-class Var;
-
-class CheckStopSlotsStatementAST : public StatementAST {
-public:
- // Constructors
- CheckStopSlotsStatementAST(VarExprAST* variable, string* condStr, string* bankStr);
-
- // Destructor
- ~CheckStopSlotsStatementAST();
-
- // Public Methods
- void generate(string& code, Type* return_type_ptr) const;
- void findResources(Map<Var*, string>& resource_list) const;
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- CheckStopSlotsStatementAST(const CheckStopSlotsStatementAST& obj);
- CheckStopSlotsStatementAST& operator=(const CheckStopSlotsStatementAST& obj);
-
- // Data Members (m_ prefix)
- VarExprAST* m_variable;
- string* m_condStr_ptr;
- string* m_bankStr_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const CheckStopSlotsStatementAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const CheckStopSlotsStatementAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //CHECKSTOPSLOTSSTATEMENTAST_H
diff --git a/src/mem/slicc/ast/CheckStopSlotsStatementAST.py b/src/mem/slicc/ast/CheckStopSlotsStatementAST.py
new file mode 100644
index 000000000..307fbd6a1
--- /dev/null
+++ b/src/mem/slicc/ast/CheckStopSlotsStatementAST.py
@@ -0,0 +1,74 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.StatementAST import StatementAST
+
+class CheckStopSlotsStatementAST(StatementAST):
+ def __init__(self, slicc, variable, condStr, bankStr):
+ super(StatementAST, self).__init__(slicc)
+ self.variable = variable
+ self.condStr = condStr
+ self.bankStr = bankStr
+
+ def __repr__(self):
+ return "[CheckStopSlotsStatementAst: %r]" % self.variable
+
+ def generate(self, code, return_type):
+ # Make sure the variable is valid
+ self.variable.var
+
+ def findResources(self, resources):
+ var = self.variable.var
+ assert var not in self.resources
+
+ check_code = code_formatter()
+ if self.condStr == "((*in_msg_ptr)).m_isOnChipSearch":
+ check_code('''
+const Response9Msg* in_msg_ptr =
+ dynamic_cast<const Response9Msg*>(((*(m_chip_ptr.m_L2Cache_responseToL2Cache9_vec[m_version]))).peek());
+assert(in_msg_ptr != NULL);
+''')
+
+ vcode = self.variable.inline()
+ bank = self.bankStr
+ cond = self.condStr
+
+ check_code('''
+if ($cond) {
+ auto pos = m_chip_ptr.m_DNUCAmover_ptr->getBankPos($bank)
+
+ if (!$vcode.isDisableSPossible(pos)) {
+ return TransitionResult_ResourceStall;
+ }
+} else {
+ if (!$vcode.isDisableFPossible(pos)) {
+ return TransitionResult_ResourceStall;
+ }
+}
+''')
+
+ resources[var] = str(check_code)
diff --git a/src/mem/slicc/ast/ChipComponentAccessAST.cc b/src/mem/slicc/ast/ChipComponentAccessAST.cc
deleted file mode 100644
index 61dccf2c0..000000000
--- a/src/mem/slicc/ast/ChipComponentAccessAST.cc
+++ /dev/null
@@ -1,244 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * ChipComponentAccessAST.C
- *
- * Description: See ChipComponentAccessAST.hh
- *
- * $Id: ChipComponentAccessAST.C 1.9 04/06/18 21:00:08-00:00 beckmann@cottons.cs.wisc.edu $
- *
- */
-
-#include "mem/slicc/ast/ChipComponentAccessAST.hh"
-
-ChipComponentAccessAST::ChipComponentAccessAST(VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* proc_name, Vector<ExprAST*>* expr_vec_ptr)
-
- : ExprAST()
-{
- m_chip_ver_expr_ptr = NULL;
- m_mach_var_ptr = machine;
- m_comp_var_ptr = component;
- m_mach_ver_expr_ptr = mach_version;
- m_expr_vec_ptr = expr_vec_ptr;
- m_proc_name_ptr = proc_name;
- m_field_name_ptr = NULL;
-}
-
-ChipComponentAccessAST::ChipComponentAccessAST(VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* field_name)
-
- : ExprAST()
-{
- m_chip_ver_expr_ptr = NULL;
- m_mach_var_ptr = machine;
- m_comp_var_ptr = component;
- m_mach_ver_expr_ptr = mach_version;
- m_expr_vec_ptr = NULL;
- m_proc_name_ptr = NULL;
- m_field_name_ptr = field_name;
-}
-
-ChipComponentAccessAST::ChipComponentAccessAST(ExprAST* chip_version, VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* proc_name, Vector<ExprAST*>* expr_vec_ptr)
-
- : ExprAST()
-{
- m_chip_ver_expr_ptr = chip_version;
- m_mach_var_ptr = machine;
- m_comp_var_ptr = component;
- m_mach_ver_expr_ptr = mach_version;
- m_expr_vec_ptr = expr_vec_ptr;
- m_proc_name_ptr = proc_name;
- m_field_name_ptr = NULL;
-}
-
-ChipComponentAccessAST::ChipComponentAccessAST(ExprAST* chip_version, VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* field_name)
-
- : ExprAST()
-{
- m_chip_ver_expr_ptr = chip_version;
- m_mach_var_ptr = machine;
- m_comp_var_ptr = component;
- m_mach_ver_expr_ptr = mach_version;
- m_expr_vec_ptr = NULL;
- m_proc_name_ptr = NULL;
- m_field_name_ptr = field_name;
-}
-
-
-
-ChipComponentAccessAST::~ChipComponentAccessAST()
-{
- if (m_expr_vec_ptr != NULL) {
- int size = m_expr_vec_ptr->size();
- for(int i=0; i<size; i++) {
- delete (*m_expr_vec_ptr)[i];
- }
- }
-
- delete m_mach_var_ptr;
- delete m_comp_var_ptr;
- delete m_mach_ver_expr_ptr;
-
- if (m_proc_name_ptr != NULL) {
- delete m_proc_name_ptr;
- }
-
- if (m_field_name_ptr != NULL) {
- delete m_field_name_ptr;
- }
-
- if (m_chip_ver_expr_ptr != NULL) {
- delete m_chip_ver_expr_ptr;
- }
-}
-
-Type* ChipComponentAccessAST::generate(string& code) const
-{
- Type* void_type_ptr = g_sym_table.getType("void");
- Type* ret_type_ptr;
-
-
- code += "(";
-
- Var* v = g_sym_table.getMachComponentVar(m_mach_var_ptr->getName(), m_comp_var_ptr->getName());
-
- string orig_code = v->getCode();
- string working_code;
-
- if (m_chip_ver_expr_ptr != NULL) {
- // replace m_chip_ptr with specified chip
-
- unsigned int t = orig_code.find("m_chip_ptr");
- assert(t != string::npos);
- string code_temp0 = orig_code.substr(0, t);
- string code_temp1 = orig_code.substr(t+10);
-
- working_code += code_temp0;
- working_code += "g_system_ptr->getChip(";
- m_chip_ver_expr_ptr->generate(working_code);
- working_code += ")";
- working_code += code_temp1;
- }
- else {
- working_code += orig_code;
- }
-
- // replace default "m_version" with the version we really want
- unsigned int tmp_uint = working_code.find("m_version");
- assert(tmp_uint != string::npos);
- string code_temp2 = working_code.substr(0, tmp_uint);
- string code_temp3 = working_code.substr(tmp_uint+9);
-
- code += code_temp2;
- code += "(";
- m_mach_ver_expr_ptr->generate(code);
- code += ")";
- code += code_temp3;
- code += ")";
-
- if (m_proc_name_ptr != NULL) {
- // method call
- code += ".";
-
- Vector <Type*> paramTypes;
-
- // generate code
- int actual_size = m_expr_vec_ptr->size();
- code += (*m_proc_name_ptr) + "(";
- for(int i=0; i<actual_size; i++) {
- if (i != 0) {
- code += ", ";
- }
- // Check the types of the parameter
- Type* actual_type_ptr = (*m_expr_vec_ptr)[i]->generate(code);
- paramTypes.insertAtBottom(actual_type_ptr);
- }
- code += ")";
-
- Type* obj_type_ptr = v->getType();
- string methodId = obj_type_ptr->methodId(*m_proc_name_ptr, paramTypes);
-
- // Verify that this is a method of the object
- if (!obj_type_ptr->methodExist(methodId)) {
- error("Invalid method call: Type '" + obj_type_ptr->toString() + "' does not have a method '" + methodId + "'");
- }
-
- int expected_size = obj_type_ptr->methodParamType(methodId).size();
- if (actual_size != expected_size) {
- // Right number of parameters
- ostringstream err;
- err << "Wrong number of parameters for function name: '" << *m_proc_name_ptr << "'";
- err << ", expected: ";
- err << expected_size;
- err << ", actual: ";
- err << actual_size;
- error(err.str());
- }
-
- for(int i=0; i<actual_size; i++) {
- // Check the types of the parameter
- Type* actual_type_ptr = paramTypes[i];
- Type* expected_type_ptr = obj_type_ptr->methodParamType(methodId)[i];
- if (actual_type_ptr != expected_type_ptr) {
- (*m_expr_vec_ptr)[i]->error("Type mismatch: expected: " + expected_type_ptr->toString() +
- " actual: " + actual_type_ptr->toString());
- }
- }
-
- // Return the return type of the method
- ret_type_ptr = obj_type_ptr->methodReturnType(methodId);
- }
- else if (m_field_name_ptr != NULL) {
- Type* obj_type_ptr = v->getType();
- code += ").m_" + (*m_field_name_ptr);
-
- // Verify that this is a valid field name for this type
- if (!obj_type_ptr->dataMemberExist(*m_field_name_ptr)) {
- error("Invalid object field: Type '" + obj_type_ptr->toString() + "' does not have data member " + *m_field_name_ptr);
- }
-
- // Return the type of the field
- ret_type_ptr = obj_type_ptr->dataMemberType(*m_field_name_ptr);
- }
- else {
- assert(0);
- }
-
- return ret_type_ptr;
-}
-
-void ChipComponentAccessAST::findResources(Map<Var*, string>& resource_list) const
-{
-
-}
-
-void ChipComponentAccessAST::print(ostream& out) const
-{
- out << "[ChipAccessExpr: " << *m_expr_vec_ptr << "]";
-}
diff --git a/src/mem/slicc/ast/ChipComponentAccessAST.hh b/src/mem/slicc/ast/ChipComponentAccessAST.hh
deleted file mode 100644
index 1f22a79e4..000000000
--- a/src/mem/slicc/ast/ChipComponentAccessAST.hh
+++ /dev/null
@@ -1,101 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- *
- *
- * Description:
- *
- * $Id: ChipComponentAccessAST.hh 1.8 04/06/18 21:00:08-00:00 beckmann@cottons.cs.wisc.edu $
- *
- */
-
-#ifndef ChipComponentAccessAST_H
-#define ChipComponentAccessAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/StatementAST.hh"
-#include "mem/slicc/ast/ExprAST.hh"
-#include "mem/slicc/ast/VarExprAST.hh"
-#include "mem/slicc/ast/TypeAST.hh"
-
-class ChipComponentAccessAST : public ExprAST {
-public:
- // Constructors
-
- // method call from local chip
- ChipComponentAccessAST(VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* proc_name, Vector<ExprAST*>* expr_vec_ptr);
- // member access from local chip
- ChipComponentAccessAST(VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* field_name);
-
- // method call from specified chip
- ChipComponentAccessAST(ExprAST* chip_version, VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* proc_name, Vector<ExprAST*>* expr_vec_ptr);
-
- // member access from specified chip
- ChipComponentAccessAST(ExprAST* chip_version, VarExprAST* machine, ExprAST* mach_version, VarExprAST* component, string* field_name);
-
- // Destructor
- ~ChipComponentAccessAST();
-
- // Public Methods
- Type* generate(string& code) const;
- void findResources(Map<Var*, string>& resource_list) const;
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- ChipComponentAccessAST(const ChipComponentAccessAST& obj);
- ChipComponentAccessAST& operator=(const ChipComponentAccessAST& obj);
-
- // Data Members (m_ prefix)
- VarExprAST* m_mach_var_ptr;
- VarExprAST* m_comp_var_ptr;
- ExprAST* m_mach_ver_expr_ptr;
- ExprAST* m_chip_ver_expr_ptr;
- Vector<ExprAST*>* m_expr_vec_ptr;
- string* m_proc_name_ptr;
- string* m_field_name_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const ChipComponentAccessAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const ChipComponentAccessAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif // ChipComponentAccessAST_H
diff --git a/src/mem/slicc/ast/ChipComponentAccessAST.py b/src/mem/slicc/ast/ChipComponentAccessAST.py
new file mode 100644
index 000000000..bbb1b61e9
--- /dev/null
+++ b/src/mem/slicc/ast/ChipComponentAccessAST.py
@@ -0,0 +1,161 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import re
+
+from slicc.ast.ExprAST import ExprAST
+from slicc.symbols import Type
+
+class ChipComponentAccessAST(ExprAST):
+ def __init__(self, slicc, machine, mach_version, component):
+ super(ChipComponentAccessAST, self).__init__(slicc)
+ self.mach_var = machine
+ self.comp_var = component
+ self.mach_ver_expr = mach_version
+
+ def __repr__(self):
+ return "[ChipAccessExpr: %r]" % self.expr_vec
+
+ def generate(self, code):
+ void_type = self.symtab.find("void", Type)
+
+ mname = self.mach_var.name
+ cname = self.comp_var.name
+ var = self.symtab.machine_components[mname][cname]
+
+ vcode = str(var.code)
+
+ if self.chip_ver_expr is not None:
+ # replace self.chip with specified chip
+ gcode = "g_system.getChip(%s)" % self.chip_ver_expr.inline()
+ vcode = re.sub("m_chip", gcode, vcode)
+
+ # replace default "m_version" with the version we really want
+ gcode = "(%s)" % self.mach_ver_expr.inline()
+ vcode = re.sub("m_version", gcode, vcode)
+
+ return_type, gcode = self.generate_access(var)
+ code("($vcode)$gcode")
+ return return_type
+
+class ChipMethodAccessAST(ChipComponentAccessAST):
+ def __init__(self, slicc, chip_version, machine, mach_version, component,
+ proc_name, expr_vec):
+ s = super(ChipMethodAccessAST, self)
+ s.__init__(slicc, machine, mach_version, component)
+
+ self.chip_ver_expr = chip_version
+ self.expr_vec = expr_vec
+ self.proc_name = proc_name
+
+ def generate_access(self, var):
+ # generate code
+ paramTypes = []
+ gcode = []
+ for expr in self.expr_vec:
+ t,c = expr.generate()
+ paramTypes.append(t)
+ gcode.append(c)
+
+ methodId = var.type.methodId(self.proc_name, paramTypes)
+
+ # Verify that this is a method of the object
+ if not var.type.methodExist(methodId):
+ self.error("%s: Type '%s' does not have a method '%s'" % \
+ ("Invalid method call", var.type, methodId))
+
+ expected_size = len(var.type.methodParamType(methodId))
+ if len(self.expr_vec) != expected_size:
+ # Right number of parameters
+ self.error("Wrong number of parameters for function name: " +\
+ "'%s', expected: %d, actual: %d",
+ self.proc_name, expected_size, len(self.expr_vec))
+
+ for expr,expected,actual in zip(self.expr_vec,
+ var.type.methodParamType(methodId),
+ paramTypes):
+ # Check the types of the parameter
+ if actual != expected:
+ expr.error("Type mismatch: expected: %s actual: %s",
+ expected, actual)
+
+ # method call
+ code = ".%s(%s)" % (self.proc_name, ', '.join(gcode))
+
+ # Return the return type of the method
+ return var.type.methodReturnType(methodId), code
+
+class LocalChipMethodAST(ChipMethodAccessAST):
+ # method call from local chip
+ def __init__(self, slicc, machine, mach_version, component, proc_name,
+ expr_vec):
+ s = super(LocalChipMethodAST, self)
+ s.__init__(slicc, None, machine, mach_version, component, proc_name,
+ expr_vec)
+
+class SpecifiedChipMethodAST(ChipMethodAccessAST):
+ # method call from specified chip
+ def __init__(self, slicc, chip_version, machine, mach_version, component,
+ proc_name, expr_vec):
+ s = super(SpecifiedChipMethodAST, self)
+ s.__init__(slicc, chip_version, machine, mach_version, component,
+ proc_name, expr_vec)
+
+class ChipMemberAccessAST(ChipComponentAccessAST):
+ # member access from specified chip
+ def __init__(self, chip_version, machine, mach_version, component,
+ field_name):
+ s = super(ChipMemberAccessAST, self)
+ s.__init__(slicc, machine, mach_version, component)
+
+ self.chip_ver_expr = chip_version
+ self.field_name = field_name
+
+ def generate_access(self, var):
+ # Verify that this is a valid field name for this type
+ if not var.type.dataMemberExist(self.field_name):
+ self.error("Invalid object field: " +\
+ "Type '%s' does not have data member %s",
+ var.type, self.field_name)
+
+ code += ").m_%s" % self.field_name
+
+ return var.type.dataMemberType(self.field_name), code
+
+class LocalChipMemberAST(ChipMemberAccessAST):
+ # member access from local chip
+ def __init__(self, slicc, machine, mach_version, component, field_name):
+ s = super(LocalChipMemberAST, self)
+ s.__init__(slicc, None, machine, mach_version, component, field_name)
+
+class SpecifiedChipMemberAST(ChipMemberAccessAST):
+ # member access from specified chip
+ def __init__(self, chip_version, machine, mach_version, component,
+ field_name):
+ s = super(SpecifiedChipMemberAST, self)
+ s.__init__(slicc, chip_version, machine, mach_version, component,
+ field_name)
diff --git a/src/mem/slicc/ast/CopyHeadStatementAST.cc b/src/mem/slicc/ast/CopyHeadStatementAST.cc
deleted file mode 100644
index 8d455eb9d..000000000
--- a/src/mem/slicc/ast/CopyHeadStatementAST.cc
+++ /dev/null
@@ -1,85 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- *
- */
-
-#include "mem/slicc/ast/CopyHeadStatementAST.hh"
-#include "mem/slicc/symbols/SymbolTable.hh"
-#include "mem/slicc/ast/VarExprAST.hh"
-#include "mem/gems_common/util.hh"
-
-CopyHeadStatementAST::CopyHeadStatementAST(VarExprAST* in_queue_ptr,
- VarExprAST* out_queue_ptr,
- PairListAST* pairs_ptr)
- : StatementAST(pairs_ptr->getPairs())
-{
- m_in_queue_ptr = in_queue_ptr;
- m_out_queue_ptr = out_queue_ptr;
-}
-
-CopyHeadStatementAST::~CopyHeadStatementAST()
-{
- delete m_in_queue_ptr;
- delete m_out_queue_ptr;
-}
-
-void CopyHeadStatementAST::generate(string& code, Type* return_type_ptr) const
-{
- m_in_queue_ptr->assertType("InPort");
- m_out_queue_ptr->assertType("OutPort");
-
- code += indent_str();
- code += m_out_queue_ptr->getVar()->getCode() + ".enqueue(" + m_in_queue_ptr->getVar()->getCode() + ".getMsgPtrCopy()";
-
- if (getPairs().exist("latency")) {
- code += ", " + getPairs().lookup("latency");
- } else {
- code += ", COPY_HEAD_LATENCY";
- }
-
- code += ");\n";
-}
-
-void CopyHeadStatementAST::findResources(Map<Var*, string>& resource_list) const
-{
- Var* var_ptr = m_out_queue_ptr->getVar();
- int res_count = 0;
- if (resource_list.exist(var_ptr)) {
- res_count = atoi((resource_list.lookup(var_ptr)).c_str());
- }
- resource_list.add(var_ptr, int_to_string(res_count+1));
-}
-
-void CopyHeadStatementAST::print(ostream& out) const
-{
- out << "[CopyHeadStatementAst: " << *m_in_queue_ptr << " " << *m_out_queue_ptr << "]";
-}
diff --git a/src/mem/slicc/ast/CopyHeadStatementAST.hh b/src/mem/slicc/ast/CopyHeadStatementAST.hh
deleted file mode 100644
index 53d479136..000000000
--- a/src/mem/slicc/ast/CopyHeadStatementAST.hh
+++ /dev/null
@@ -1,87 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- *
- */
-
-#ifndef COPYHEADSTATEMENTAST_H
-#define COPYHEADTATEMENTAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/StatementAST.hh"
-#include "mem/slicc/ast/StatementListAST.hh"
-#include "mem/slicc/ast/TypeAST.hh"
-#include "mem/slicc/ast/PairListAST.hh"
-
-class VarExprAST;
-class Var;
-
-class CopyHeadStatementAST : public StatementAST {
-public:
- // Constructors
- CopyHeadStatementAST(VarExprAST* in_queue_ptr,
- VarExprAST* out_queue_ptr,
- PairListAST* pairs_ptr);
-
- // Destructor
- ~CopyHeadStatementAST();
-
- // Public Methods
- void generate(string& code, Type* return_type_ptr) const;
- void findResources(Map<Var*, string>& resource_list) const;
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- CopyHeadStatementAST(const CopyHeadStatementAST& obj);
- CopyHeadStatementAST& operator=(const CopyHeadStatementAST& obj);
-
- // Data Members (m_ prefix)
- VarExprAST* m_in_queue_ptr;
- VarExprAST* m_out_queue_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const CopyHeadStatementAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const CopyHeadStatementAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //COPYHEADSTATEMENTAST_H
diff --git a/src/mem/slicc/ast/CopyHeadStatementAST.py b/src/mem/slicc/ast/CopyHeadStatementAST.py
new file mode 100644
index 000000000..ba9970975
--- /dev/null
+++ b/src/mem/slicc/ast/CopyHeadStatementAST.py
@@ -0,0 +1,52 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.StatementAST import StatementAST
+
+class CopyHeadStatementAST(StatementAST):
+ def __init__(self, slicc, in_queue, out_queue, pairs):
+ super(CopyHeadStatementAST, self).__init__(slicc, pairs)
+
+ self.in_queue = in_queue
+ self.out_queue_ptr = out_queue
+
+ def __repr__(self):
+ return "[CopyHeadStatementAst: %r %r]" % (self.in_queue,
+ self.out_queue)
+
+ def generate(self, code, return_type):
+ self.in_queue.assertType("InPort")
+ self.out_queue.assertType("OutPort")
+
+ out_code = self.out_queue.var.code
+ in_code = self.in_queue.var.code
+ latency = self.get("latency", "COPY_HEAD_LATENCY")
+ code("$out_code.enqueue($in_code.getMsgPtrCopy(), $latency);")
+
+ def findResources(self, resources):
+ var = self.out_queue.var
+ resources[var] = str(int(resources.get(var, "0")) + 1)
diff --git a/src/mem/slicc/ast/DeclAST.py b/src/mem/slicc/ast/DeclAST.py
new file mode 100644
index 000000000..1adb31321
--- /dev/null
+++ b/src/mem/slicc/ast/DeclAST.py
@@ -0,0 +1,38 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.AST import AST
+
+class DeclAST(AST):
+ def __init__(self, slicc, pairs):
+ super(DeclAST, self).__init__(slicc, pairs)
+
+ def files(self, parent=None):
+ return set()
+
+ def findMachines(self):
+ return
diff --git a/src/mem/slicc/ast/DeclListAST.hh b/src/mem/slicc/ast/DeclListAST.hh
deleted file mode 100644
index 1c2bc3c05..000000000
--- a/src/mem/slicc/ast/DeclListAST.hh
+++ /dev/null
@@ -1,84 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * DeclListAST.hh
- *
- * Description:
- *
- * $Id: DeclListAST.hh,v 3.1 2001/12/12 01:00:12 milo Exp $
- *
- */
-
-#ifndef DeclListAST_H
-#define DeclListAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/AST.hh"
-#include "mem/slicc/ast/DeclAST.hh"
-
-class DeclListAST : public AST {
-public:
- // Constructors
- DeclListAST(Vector<DeclAST*>* vec_ptr);
- DeclListAST(DeclAST* statement_ptr);
-
- // Destructor
- ~DeclListAST();
-
- // Public Methods
- void generate() const;
- void findMachines() const;
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- DeclListAST(const DeclListAST& obj);
- DeclListAST& operator=(const DeclListAST& obj);
-
- // Data Members (m_ prefix)
- Vector<DeclAST*>* m_vec_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const DeclListAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const DeclListAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //DeclListAST_H
diff --git a/src/mem/slicc/ast/DeclListAST.py b/src/mem/slicc/ast/DeclListAST.py
new file mode 100644
index 000000000..36c520070
--- /dev/null
+++ b/src/mem/slicc/ast/DeclListAST.py
@@ -0,0 +1,53 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.AST import AST
+
+class DeclListAST(AST):
+ def __init__(self, slicc, decls):
+ super(DeclListAST, self).__init__(slicc)
+
+ if not isinstance(decls, (list, tuple)):
+ decls = [ decls ]
+ self.decls = decls
+
+ def __repr__(self):
+ return "[DeclListAST: %s]" % (', '.join(repr(d) for d in self.decls))
+
+ def files(self, parent=None):
+ s = set()
+ for decl in self.decls:
+ s |= decl.files(parent)
+ return s
+
+ def generate(self):
+ for decl in self.decls:
+ decl.generate()
+
+ def findMachines(self):
+ for decl in self.decls:
+ decl.findMachines()
diff --git a/src/mem/slicc/ast/EnqueueStatementAST.cc b/src/mem/slicc/ast/EnqueueStatementAST.cc
deleted file mode 100644
index a422d8a28..000000000
--- a/src/mem/slicc/ast/EnqueueStatementAST.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- *
- */
-
-#include "mem/slicc/ast/EnqueueStatementAST.hh"
-#include "mem/slicc/symbols/SymbolTable.hh"
-#include "mem/slicc/ast/VarExprAST.hh"
-#include "mem/slicc/ast/PairListAST.hh"
-#include "mem/gems_common/util.hh"
-
-EnqueueStatementAST::EnqueueStatementAST(VarExprAST* queue_name_ptr,
- TypeAST* type_name_ptr,
- PairListAST* pairs_ptr,
- StatementListAST* statement_list_ast_ptr)
- : StatementAST(pairs_ptr->getPairs())
-{
- m_queue_name_ptr = queue_name_ptr;
- m_type_name_ptr = type_name_ptr;
- m_statement_list_ast_ptr = statement_list_ast_ptr;
-}
-
-EnqueueStatementAST::~EnqueueStatementAST()
-{
- delete m_queue_name_ptr;
- delete m_type_name_ptr;
- delete m_statement_list_ast_ptr;
-}
-
-void EnqueueStatementAST::generate(string& code, Type* return_type_ptr) const
-{
- code += indent_str() + "{\n"; // Start scope
- inc_indent();
- g_sym_table.pushFrame();
-
- Type* msg_type_ptr = m_type_name_ptr->lookupType();
-
- // Add new local var to symbol table
- g_sym_table.newSym(new Var("out_msg", getLocation(), msg_type_ptr, "out_msg", getPairs()));
-
- code += indent_str() + msg_type_ptr->cIdent() + " out_msg;\n"; // Declare message
- m_statement_list_ast_ptr->generate(code, NULL); // The other statements
-
- code += indent_str();
-
- m_queue_name_ptr->assertType("OutPort");
- code += "(" + m_queue_name_ptr->getVar()->getCode() + ")";
- code += ".enqueue(out_msg";
-
- if (getPairs().exist("latency")) {
- bool is_number = true;
- string val = getPairs().lookup("latency");
- for (int i=0; i<val.size(); i++)
- if (!isdigit(val[i])) is_number = false;
- if (is_number)
- code += ", " + getPairs().lookup("latency");
- else
- code += ", m_" + getPairs().lookup("latency");
- }
-
- code += ");\n";
-
- dec_indent();
- g_sym_table.popFrame();
- code += indent_str() + "}\n"; // End scope
-}
-
-void EnqueueStatementAST::findResources(Map<Var*, string>& resource_list) const
-{
- Var* var_ptr = m_queue_name_ptr->getVar();
- int res_count = 0;
- if (resource_list.exist(var_ptr)) {
- res_count = atoi((resource_list.lookup(var_ptr)).c_str());
- }
- resource_list.add(var_ptr, int_to_string(res_count+1));
-}
-
-void EnqueueStatementAST::print(ostream& out) const
-{
- out << "[EnqueueStatementAst: " << *m_queue_name_ptr << " "
- << m_type_name_ptr->toString() << " " << *m_statement_list_ast_ptr << "]";
-}
diff --git a/src/mem/slicc/ast/EnqueueStatementAST.hh b/src/mem/slicc/ast/EnqueueStatementAST.hh
deleted file mode 100644
index fc2776ed7..000000000
--- a/src/mem/slicc/ast/EnqueueStatementAST.hh
+++ /dev/null
@@ -1,93 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * EnqueueStatementAST.hh
- *
- * Description:
- *
- * $Id$
- *
- */
-
-#ifndef ENQUEUESTATEMENTAST_H
-#define ENQUEUESTATEMENTAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/StatementAST.hh"
-#include "mem/slicc/ast/StatementListAST.hh"
-#include "mem/slicc/ast/TypeAST.hh"
-
-class VarExprAST;
-class Var;
-class PairListAST;
-
-class EnqueueStatementAST : public StatementAST {
-public:
- // Constructors
- EnqueueStatementAST(VarExprAST* queue_name_ptr,
- TypeAST* type_name_ptr,
- PairListAST* pairs_ptr,
- StatementListAST* statement_list_ast_ptr);
-
- // Destructor
- ~EnqueueStatementAST();
-
- // Public Methods
- void generate(string& code, Type* return_type_ptr) const;
- void findResources(Map<Var*, string>& resource_list) const;
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- EnqueueStatementAST(const EnqueueStatementAST& obj);
- EnqueueStatementAST& operator=(const EnqueueStatementAST& obj);
-
- // Data Members (m_ prefix)
- VarExprAST* m_queue_name_ptr;
- TypeAST* m_type_name_ptr;
- StatementListAST* m_statement_list_ast_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const EnqueueStatementAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const EnqueueStatementAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //ENQUEUESTATEMENTAST_H
diff --git a/src/mem/slicc/ast/EnqueueStatementAST.py b/src/mem/slicc/ast/EnqueueStatementAST.py
new file mode 100644
index 000000000..faf966460
--- /dev/null
+++ b/src/mem/slicc/ast/EnqueueStatementAST.py
@@ -0,0 +1,86 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.StatementAST import StatementAST
+from slicc.symbols import Var
+
+class EnqueueStatementAST(StatementAST):
+ def __init__(self, slicc, queue_name, type_ast, pairs, statements):
+ super(EnqueueStatementAST, self).__init__(slicc, pairs)
+
+ self.queue_name = queue_name
+ self.type_ast = type_ast
+ self.statements = statements
+
+ def __repr__(self):
+ return "[EnqueueStatementAst: %s %s %s]" % \
+ (self.queue_name, self.type_ast.ident, self.statements)
+
+ def generate(self, code, return_type):
+ code("{")
+ code.indent()
+ self.symtab.pushFrame()
+
+ msg_type = self.type_ast.type
+
+ # Add new local var to symbol table
+ v = Var(self.symtab, "out_msg", self.location, msg_type, "out_msg",
+ self.pairs)
+ self.symtab.newSymbol(v)
+
+ # Declare message
+ code("${{msg_type.ident}} out_msg;")
+
+ # The other statements
+ t = self.statements.generate(code, None)
+
+ self.queue_name.assertType("OutPort")
+
+ args = [ "out_msg" ]
+ if "latency" in self:
+ latency = self["latency"]
+ try:
+ # see if this is an integer
+ latency = int(latency)
+ args.append("%s" % latency)
+ except ValueError:
+ # if not, it should be a member
+ args.append("m_%s" % latency)
+
+ args = ", ".join(args)
+ code('(${{self.queue_name.var.code}}).enqueue($args);')
+
+
+ # End scope
+ self.symtab.popFrame()
+ code.dedent()
+ code("}")
+
+ def findResources(self, resources):
+ var = self.queue_name.var
+ res_count = int(resources.get(var, 0))
+ resources[var] = str(res_count + 1)
diff --git a/src/mem/slicc/ast/EnumDeclAST.cc b/src/mem/slicc/ast/EnumDeclAST.cc
deleted file mode 100644
index b051f3c8f..000000000
--- a/src/mem/slicc/ast/EnumDeclAST.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * EnumDeclAST.C
- *
- * Description: See EnumDeclAST.hh
- *
- * $Id$
- *
- */
-
-#include "mem/slicc/ast/EnumDeclAST.hh"
-#include "mem/slicc/main.hh"
-#include "mem/slicc/symbols/SymbolTable.hh"
-
-EnumDeclAST::EnumDeclAST(TypeAST* type_ast_ptr,
- PairListAST* pairs_ptr,
- Vector<TypeFieldAST*>* field_vec_ptr)
- : DeclAST(pairs_ptr)
-{
- m_type_ast_ptr = type_ast_ptr;
- m_field_vec_ptr = field_vec_ptr;
-}
-
-EnumDeclAST::~EnumDeclAST()
-{
- delete m_type_ast_ptr;
- if (m_field_vec_ptr != NULL) {
- int size = m_field_vec_ptr->size();
- for(int i=0; i<size; i++) {
- delete (*m_field_vec_ptr)[i];
- }
- delete m_field_vec_ptr;
- }
-}
-
-void EnumDeclAST::generate()
-{
- string machine_name;
- string id = m_type_ast_ptr->toString();
-
- Vector<Type*> param_type_vec; // used by to_string func call
-
- // Make the new type
- Type* new_type_ptr = new Type(id, getLocation(), getPairs(),
- g_sym_table.getStateMachine());
- g_sym_table.newSym(new_type_ptr);
-
- // Add all of the fields of the type to it
- if (m_field_vec_ptr != NULL) {
- int size = m_field_vec_ptr->size();
- for(int i=0; i<size; i++) {
- (*m_field_vec_ptr)[i]->generate(new_type_ptr);
- }
- }
-
- // Add the implicit State_to_string method - FIXME, this is a bit dirty
- param_type_vec.insertAtBottom(new_type_ptr); // add state to param vector
- string func_id = new_type_ptr->cIdent()+"_to_string";
-
- Map<string, string> pairs;
- pairs.add("external", "yes");
- Vector<string> string_vec;
- g_sym_table.newSym(new Func(func_id, getLocation(), g_sym_table.getType("string"), param_type_vec, string_vec, string(""), pairs, NULL));
-}
-
-void EnumDeclAST::print(ostream& out) const
-{
- out << "[EnumDecl: " << m_type_ast_ptr->toString() << "]";
-}
-
diff --git a/src/mem/slicc/ast/EnumDeclAST.hh b/src/mem/slicc/ast/EnumDeclAST.hh
deleted file mode 100644
index 2af650e83..000000000
--- a/src/mem/slicc/ast/EnumDeclAST.hh
+++ /dev/null
@@ -1,86 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * EnummDeclAST.hh
- *
- * Description:
- *
- * $Id$
- *
- */
-
-#ifndef EnumDeclAST_H
-#define EnumDeclAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/DeclAST.hh"
-#include "mem/slicc/ast/TypeAST.hh"
-#include "mem/slicc/ast/TypeFieldAST.hh"
-
-class EnumDeclAST : public DeclAST {
-public:
- // Constructors
- EnumDeclAST(TypeAST* type_ast_ptr,
- PairListAST* pairs_ptr,
- Vector<TypeFieldAST*>* field_vec_ptr);
-
- // Destructor
- ~EnumDeclAST();
-
- // Public Methods
- virtual void generate();
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- EnumDeclAST(const EnumDeclAST& obj);
- EnumDeclAST& operator=(const EnumDeclAST& obj);
-
- // Data Members (m_ prefix)
- TypeAST* m_type_ast_ptr;
- Vector<TypeFieldAST*>* m_field_vec_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const EnumDeclAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const EnumDeclAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //EnumDeclAST_H
diff --git a/src/mem/slicc/ast/EnumDeclAST.py b/src/mem/slicc/ast/EnumDeclAST.py
new file mode 100644
index 000000000..a20f4b749
--- /dev/null
+++ b/src/mem/slicc/ast/EnumDeclAST.py
@@ -0,0 +1,71 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.DeclAST import DeclAST
+from slicc.symbols import Func, Type
+
+class EnumDeclAST(DeclAST):
+ def __init__(self, slicc, type_ast, pairs, fields):
+ super(EnumDeclAST, self).__init__(slicc, pairs)
+
+ self.type_ast = type_ast
+ self.fields = fields
+
+ def __repr__(self):
+ return "[EnumDecl: %s]" % (self.type_ast)
+
+ def files(self, parent=None):
+ if "external" in self:
+ return set()
+
+ if parent:
+ ident = "%s_%s" % (parent, self.type_ast.ident)
+ else:
+ ident = self.type_ast.ident
+ s = set(("%s.hh" % ident, "%s.cc" % ident))
+ return s
+
+ def generate(self):
+ ident = str(self.type_ast)
+
+ # Make the new type
+ t = Type(self.symtab, ident, self.location, self.pairs,
+ self.state_machine)
+ self.symtab.newSymbol(t)
+
+ # Add all of the fields of the type to it
+ for field in self.fields:
+ field.generate(t)
+
+ # Add the implicit State_to_string method - FIXME, this is a bit dirty
+ func_id = "%s_to_string" % t.c_ident
+
+ pairs = { "external" : "yes" }
+ func = Func(self.symtab, func_id, self.location,
+ self.symtab.find("string", Type), [ t ], [], "",
+ pairs, None)
+ self.symtab.newSymbol(func)
diff --git a/src/mem/slicc/ast/EnumExprAST.hh b/src/mem/slicc/ast/EnumExprAST.hh
deleted file mode 100644
index 8af1c8891..000000000
--- a/src/mem/slicc/ast/EnumExprAST.hh
+++ /dev/null
@@ -1,85 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * EnumExprAST.hh
- *
- * Description:
- *
- * $Id: EnumExprAST.hh,v 3.2 2003/07/10 18:08:06 milo Exp $
- *
- */
-
-#ifndef EnumExprAST_H
-#define EnumExprAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/ExprAST.hh"
-#include "mem/slicc/ast/TypeAST.hh"
-
-
-class EnumExprAST : public ExprAST {
-public:
- // Constructors
- EnumExprAST(TypeAST* type_ast_ptr,
- string* value_ptr);
-
- // Destructor
- ~EnumExprAST();
-
- // Public Methods
- Type* generate(string& code) const;
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- EnumExprAST(const EnumExprAST& obj);
- EnumExprAST& operator=(const EnumExprAST& obj);
-
- // Data Members (m_ prefix)
- TypeAST* m_type_ast_ptr;
- string* m_value_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const EnumExprAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const EnumExprAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //EnumExprAST_H
diff --git a/src/mem/slicc/ast/EnumExprAST.py b/src/mem/slicc/ast/EnumExprAST.py
new file mode 100644
index 000000000..9cb76a8a1
--- /dev/null
+++ b/src/mem/slicc/ast/EnumExprAST.py
@@ -0,0 +1,53 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.ExprAST import ExprAST
+
+class EnumExprAST(ExprAST):
+ def __init__(self, slicc, type_ast, value):
+ super(EnumExprAST, self).__init__(slicc)
+
+ assert type_ast
+ assert value
+
+ self.type_ast = type_ast
+ self.value = value
+
+ def __repr__(self):
+ return "[EnumExpr: %s:%s]" % (self.type_ast, self.value)
+
+ def generate(self, code):
+ fix = code.nofix()
+ code('${{self.type_ast.type.c_ident}}_${{self.value}}')
+ code.fix(fix)
+
+ # Make sure the enumeration value exists
+ if self.value not in self.type_ast.type.enums:
+ self.error("Type '%s' does not have enumeration '%s'",
+ self.type_ast, self.value)
+
+ return self.type_ast.type
diff --git a/src/mem/slicc/ast/ExprAST.cc b/src/mem/slicc/ast/ExprAST.cc
deleted file mode 100644
index 3427d4dd9..000000000
--- a/src/mem/slicc/ast/ExprAST.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * ExprAST.C
- *
- * Description: See ExprAST.hh
- *
- * $Id$
- *
- */
-
-#include "mem/slicc/ast/ExprAST.hh"
diff --git a/src/mem/slicc/ast/ExprAST.py b/src/mem/slicc/ast/ExprAST.py
new file mode 100644
index 000000000..70a0aa0b5
--- /dev/null
+++ b/src/mem/slicc/ast/ExprAST.py
@@ -0,0 +1,45 @@
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.util import code_formatter
+
+from slicc.ast.AST import AST
+
+class ExprAST(AST):
+ def __init__(self, slicc):
+ super(ExprAST, self).__init__(slicc)
+
+ def findResources(self, resources):
+ # The default is no resources
+ pass
+
+ def inline(self, get_type=False):
+ code = code_formatter(fix_newlines=False)
+ return_type = self.generate(code)
+ if get_type:
+ return return_type, code
+ else:
+ return code
diff --git a/src/mem/slicc/ast/ExprStatementAST.hh b/src/mem/slicc/ast/ExprStatementAST.hh
deleted file mode 100644
index a47e86af5..000000000
--- a/src/mem/slicc/ast/ExprStatementAST.hh
+++ /dev/null
@@ -1,83 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * ExprStatementAST.hh
- *
- * Description:
- *
- * $Id$
- *
- */
-
-#ifndef ExprStatementAST_H
-#define ExprStatementAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/StatementAST.hh"
-#include "mem/slicc/ast/ExprAST.hh"
-
-class ExprStatementAST : public StatementAST {
-public:
- // Constructors
- ExprStatementAST(ExprAST* expr_ptr);
-
- // Destructor
- ~ExprStatementAST();
-
- // Public Methods
- void generate(string& code, Type* return_type_ptr) const;
- void findResources(Map<Var*, string>& resource_list) const;
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- ExprStatementAST(const ExprStatementAST& obj);
- ExprStatementAST& operator=(const ExprStatementAST& obj);
-
- // Data Members (m_ prefix)
- ExprAST* m_expr_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const ExprStatementAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const ExprStatementAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //ExprStatementAST_H
diff --git a/src/mem/slicc/ast/ExprStatementAST.py b/src/mem/slicc/ast/ExprStatementAST.py
new file mode 100644
index 000000000..b16d1d072
--- /dev/null
+++ b/src/mem/slicc/ast/ExprStatementAST.py
@@ -0,0 +1,52 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.util import code_formatter
+
+from slicc.ast.StatementAST import StatementAST
+from slicc.symbols import Type
+
+class ExprStatementAST(StatementAST):
+ def __init__(self, slicc, expr):
+ super(ExprStatementAST, self).__init__(slicc)
+ self.expr = expr
+
+ def __repr__(self):
+ return "[ExprStatementAST: %s]" % (self.expr)
+
+ def generate(self, code, return_type):
+ actual_type,rcode = self.expr.inline(True)
+ code("$rcode;")
+
+ # The return type must be void
+ if actual_type != self.symtab.find("void", Type):
+ self.expr.error("Non-void return must not be ignored, " + \
+ "return type is '%s'", actual_type.ident)
+
+ def findResources(self, resources):
+ self.expr.findResources(resources)
+
diff --git a/src/mem/slicc/ast/FormalParamAST.cc b/src/mem/slicc/ast/FormalParamAST.cc
deleted file mode 100644
index 529811f25..000000000
--- a/src/mem/slicc/ast/FormalParamAST.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * FormalParamAST.C
- *
- * Description: See FormalParamAST.hh
- *
- * $Id: FormalParamAST.C,v 3.1 2000/10/05 21:22:20 milo Exp $
- *
- */
-
-#include "mem/slicc/ast/FormalParamAST.hh"
-#include "mem/slicc/ast/StatementAST.hh"
-#include "mem/slicc/ast/TypeAST.hh"
-#include "mem/slicc/symbols/SymbolTable.hh"
-
-FormalParamAST::~FormalParamAST()
-{
- delete m_ident_ptr;
- delete m_type_ast_ptr;
-}
-
-string FormalParamAST::getTypeName() const
-{
- return m_type_ast_ptr->toString();
-}
-
-Type* FormalParamAST::getType() const
-{
- return m_type_ast_ptr->lookupType();
-}
-
-Type* FormalParamAST::generate(string& code) const
-{
- string param = "param_" + *m_ident_ptr;
-
- Type* type_ptr = m_type_ast_ptr->lookupType();
- code += type_ptr->cIdent();
- code += " ";
- code += param;
-
- // Add to symbol table
- g_sym_table.newSym(new Var(*m_ident_ptr, getLocation(), type_ptr, param, getPairs()));
- return type_ptr;
-}
diff --git a/src/mem/slicc/ast/FormalParamAST.hh b/src/mem/slicc/ast/FormalParamAST.hh
deleted file mode 100644
index ca27948b7..000000000
--- a/src/mem/slicc/ast/FormalParamAST.hh
+++ /dev/null
@@ -1,88 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * FormalParamAST.hh
- *
- * Description:
- *
- * $Id: FormalParamAST.hh,v 3.1 2001/12/12 01:00:15 milo Exp $
- *
- */
-
-#ifndef FORMALPARAMAST_H
-#define FORMALPARAMAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/AST.hh"
-
-class TypeAST;
-
-
-class FormalParamAST : public AST {
-public:
- // Constructors
- FormalParamAST(TypeAST* type_ast_ptr, string* ident_ptr) : AST() { m_type_ast_ptr = type_ast_ptr; m_ident_ptr = ident_ptr; }
-
- // Destructor
- ~FormalParamAST();
-
- // Public Methods
- Type* generate(string& code) const;
- void print(ostream& out) const { out << "[FormalParamAST: " << *m_ident_ptr << "]"; }
- string getName() const { return *m_ident_ptr; }
- string getTypeName() const;
- Type* getType() const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- FormalParamAST(const FormalParamAST& obj);
- FormalParamAST& operator=(const FormalParamAST& obj);
-
- // Data Members (m_ prefix)
- string* m_ident_ptr;
- TypeAST* m_type_ast_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const FormalParamAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const FormalParamAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //FORMALPARAMAST_H
diff --git a/src/mem/slicc/ast/FormalParamAST.py b/src/mem/slicc/ast/FormalParamAST.py
new file mode 100644
index 000000000..b169cbb1c
--- /dev/null
+++ b/src/mem/slicc/ast/FormalParamAST.py
@@ -0,0 +1,52 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.AST import AST
+from slicc.symbols import Var
+
+class FormalParamAST(AST):
+ def __init__(self, slicc, type_ast, ident):
+ super(FormalParamAST, self).__init__(slicc)
+ self.type_ast = type_ast
+ self.ident = ident
+
+ def __repr__(self):
+ return "[FormalParamAST: %s]" % self.ident
+
+ @property
+ def name(self):
+ return self.ident
+
+ def generate(self):
+ type = self.type_ast.type
+ param = "param_%s" % self.ident
+
+ # Add to symbol table
+ v = Var(self.symtab, self.ident, self.location, type, param,
+ self.pairs)
+ self.symtab.newSymbol(v)
+ return type, "%s %s" % (type.c_ident, param)
diff --git a/src/mem/slicc/ast/FuncCallExprAST.cc b/src/mem/slicc/ast/FuncCallExprAST.cc
deleted file mode 100644
index 5b19017e9..000000000
--- a/src/mem/slicc/ast/FuncCallExprAST.cc
+++ /dev/null
@@ -1,224 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * FuncCallExprAST.C
- *
- * Description: See FuncCallExprAST.hh
- *
- * $Id$
- *
- */
-
-#include "mem/slicc/ast/FuncCallExprAST.hh"
-#include "mem/slicc/symbols/SymbolTable.hh"
-
-FuncCallExprAST::FuncCallExprAST(string* proc_name_ptr,
- Vector<ExprAST*>* expr_vec_ptr)
- : ExprAST()
-{
- m_proc_name_ptr = proc_name_ptr;
- m_expr_vec_ptr = expr_vec_ptr;
-}
-
-FuncCallExprAST::~FuncCallExprAST()
-{
- delete m_proc_name_ptr;
- int size = m_expr_vec_ptr->size();
- for(int i=0; i<size; i++) {
- delete (*m_expr_vec_ptr)[i];
- }
- delete m_expr_vec_ptr;
-}
-
-Type* FuncCallExprAST::generate(string& code) const
-{
- // DEBUG_EXPR is strange since it takes parameters of multiple types
- if (*m_proc_name_ptr == "DEBUG_EXPR") {
- // FIXME - check for number of parameters
- code += "DEBUG_SLICC(MedPrio, \"";
- code += (*m_expr_vec_ptr)[0]->getLocation().toString();
- code += ": \", ";
- (*m_expr_vec_ptr)[0]->generate(code);
- code += ");\n";
- Type* void_type_ptr = g_sym_table.getType("void");
- assert(void_type_ptr != NULL);
- return void_type_ptr;
- }
-
- // hack for adding comments to profileTransition
- if (*m_proc_name_ptr == "APPEND_TRANSITION_COMMENT") {
- // FIXME - check for number of parameters
- code += "APPEND_TRANSITION_COMMENT(";
- //code += (*m_expr_vec_ptr)[0]->getLocation().toString();
- //code += ": \", ";
- (*m_expr_vec_ptr)[0]->generate(code);
- code += ");\n";
- Type* void_type_ptr = g_sym_table.getType("void");
- assert(void_type_ptr != NULL);
- return void_type_ptr;
- }
-
- // Look up the function in the symbol table
- Vector<string> code_vec;
- Func* func_ptr = g_sym_table.getFunc(*m_proc_name_ptr);
-
- // Check the types and get the code for the parameters
- if (func_ptr == NULL) {
- error("Unrecognized function name: '" + *m_proc_name_ptr + "'");
- } else {
- int size = m_expr_vec_ptr->size();
-
- Vector<Type*> f = func_ptr->getParamTypes();
-
- if (size != f.size() ) {
- error("Wrong number of arguments passed to function : '" + *m_proc_name_ptr + "'");
- }
- else {
- for(int i=0; i<size; i++) {
-
- // Check the types of the parameter
- string param_code;
- Type* actual_type_ptr = (*m_expr_vec_ptr)[i]->generate(param_code);
- Type* expected_type_ptr = func_ptr->getParamTypes()[i];
- if (actual_type_ptr != expected_type_ptr) {
- (*m_expr_vec_ptr)[i]->error("Type mismatch: expected: " + expected_type_ptr->toString() +
- " actual: " + actual_type_ptr->toString());
- }
- code_vec.insertAtBottom(param_code);
- }
- }
- }
-
- /* OK, the semantics of "trigger" here is that, ports in the machine have
- * different priorities. We always check the first port for doable
- * transitions. If nothing/stalled, we pick one from the next port.
- *
- * One thing we have to be careful as the SLICC protocol writter is :
- * If a port have two or more transitions can be picked from in one cycle,
- * they must be independent. Otherwise, if transition A and B mean to be
- * executed in sequential, and A get stalled, transition B can be issued
- * erroneously. In practice, in most case, there is only one transition
- * should be executed in one cycle for a given port. So as most of current
- * protocols.
- */
-
- if (*m_proc_name_ptr == "trigger") {
- code += indent_str() + "{\n";
- code += indent_str() + " Address addr = ";
- code += code_vec[1];
- code += ";\n";
- code += indent_str() + " TransitionResult result = doTransition(";
- code += code_vec[0];
- code += ", " + g_sym_table.getStateMachine()->toString() + "_getState(addr), addr";
- if(CHECK_INVALID_RESOURCE_STALLS) {
- // FIXME - the current assumption is that in_buffer_rank is declared in the msg buffer peek statement
- code += ", in_buffer_rank";
- }
- code += ");\n";
- code += indent_str() + " if (result == TransitionResult_Valid) {\n";
- code += indent_str() + " counter++;\n";
- code += indent_str() + " continue; // Check the first port again\n";
- code += indent_str() + " }\n";
- code += indent_str() + " if (result == TransitionResult_ResourceStall) {\n";
- code += indent_str() + " g_eventQueue_ptr->scheduleEvent(this, 1);\n";
- code += indent_str() + " // Cannot do anything with this transition, go check next doable transition (mostly likely of next port)\n";
- code += indent_str() + " }\n";
- code += indent_str() + "}\n";
- } else if (*m_proc_name_ptr == "doubleTrigger") {
- // NOTE: Use the doubleTrigger call with extreme caution
- // the key to double trigger is the second event triggered cannot fail becuase the first event cannot be undone
- assert(code_vec.size() == 4);
- code += indent_str() + "{\n";
- code += indent_str() + " Address addr1 = ";
- code += code_vec[1];
- code += ";\n";
- code += indent_str() + " TransitionResult result1 = doTransition(";
- code += code_vec[0];
- code += ", " + g_sym_table.getStateMachine()->toString() + "_getState(addr1), addr1";
- if(CHECK_INVALID_RESOURCE_STALLS) {
- // FIXME - the current assumption is that in_buffer_rank is declared in the msg buffer peek statement
- code += ", in_buffer_rank";
- }
- code += ");\n";
- code += indent_str() + " if (result1 == TransitionResult_Valid) {\n";
- code += indent_str() + " //this second event cannont fail because the first event already took effect\n";
- code += indent_str() + " Address addr2 = ";
- code += code_vec[3];
- code += ";\n";
- code += indent_str() + " TransitionResult result2 = doTransition(";
- code += code_vec[2];
- code += ", " + g_sym_table.getStateMachine()->toString() + "_getState(addr2), addr2";
- if(CHECK_INVALID_RESOURCE_STALLS) {
- // FIXME - the current assumption is that in_buffer_rank is declared in the msg buffer peek statement
- code += ", in_buffer_rank";
- }
- code += ");\n";
- code += indent_str() + " assert(result2 == TransitionResult_Valid); // ensure the event suceeded\n";
- code += indent_str() + " counter++;\n";
- code += indent_str() + " continue; // Check the first port again\n";
- code += indent_str() + " }\n";
- code += indent_str() + " if (result1 == TransitionResult_ResourceStall) {\n";
- code += indent_str() + " g_eventQueue_ptr->scheduleEvent(this, 1);\n";
- code += indent_str() + " // Cannot do anything with this transition, go check next doable transition (mostly likely of next port)\n";
- code += indent_str() + " }\n";
- code += indent_str() + "}\n";
- } else if (*m_proc_name_ptr == "error") {
- code += indent_str() + (*m_expr_vec_ptr)[0]->embedError(code_vec[0]) + "\n";
- } else if (*m_proc_name_ptr == "assert") {
- code += indent_str() + "if (ASSERT_FLAG && !(" + code_vec[0] + ")) {\n";
- code += indent_str() + " " + (*m_expr_vec_ptr)[0]->embedError("\"assert failure\"") + "\n";
- code += indent_str() + "}\n";
- } else if (*m_proc_name_ptr == "continueProcessing") {
- code += "counter++; continue; // Check the first port again";
- } else {
- // Normal function
- code += "(";
- // if the func is internal to the chip but not the machine then it can only be
- // accessed through the chip pointer
- if (!func_ptr->existPair("external") && !func_ptr->isInternalMachineFunc()) {
- code += "m_chip_ptr->";
- }
- code += func_ptr->cIdent() + "(";
- int size = code_vec.size();
- for(int i=0; i<size; i++) {
- if (i != 0) {
- code += ", ";
- }
- code += code_vec[i];
- }
- code += "))";
- }
- return func_ptr->getReturnType();
-}
-
-void FuncCallExprAST::print(ostream& out) const
-{
- out << "[FuncCallExpr: " << *m_proc_name_ptr << " " << *m_expr_vec_ptr << "]";
-}
diff --git a/src/mem/slicc/ast/FuncCallExprAST.hh b/src/mem/slicc/ast/FuncCallExprAST.hh
deleted file mode 100644
index 6c02122ee..000000000
--- a/src/mem/slicc/ast/FuncCallExprAST.hh
+++ /dev/null
@@ -1,89 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * FuncCallExprAST.hh
- *
- * Description:
- *
- * $Id$
- *
- */
-
-#ifndef FUNCCALLEXPRAST_H
-#define FUNCCALLEXPRAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/StatementAST.hh"
-#include "mem/slicc/ast/ExprAST.hh"
-
-
-// ProcGen decl
-class FuncGen;
-
-class FuncCallExprAST : public ExprAST {
-public:
- // Constructors
- FuncCallExprAST(string* proc_name_ptr,
- Vector<ExprAST*>* expr_vec_ptr);
-
- // Destructor
- ~FuncCallExprAST();
-
- // Public Methods
- Type* generate(string& code) const;
- void print(ostream& out) const;
-
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- FuncCallExprAST(const FuncCallExprAST& obj);
- FuncCallExprAST& operator=(const FuncCallExprAST& obj);
-
- // Data Members (m_ prefix)
- string* m_proc_name_ptr;
- Vector<ExprAST*>* m_expr_vec_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const FuncCallExprAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const FuncCallExprAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //FUNCCALLEXPRAST_H
diff --git a/src/mem/slicc/ast/FuncCallExprAST.py b/src/mem/slicc/ast/FuncCallExprAST.py
new file mode 100644
index 000000000..abf7eec7b
--- /dev/null
+++ b/src/mem/slicc/ast/FuncCallExprAST.py
@@ -0,0 +1,168 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.ExprAST import ExprAST
+from slicc.symbols import Func, Type
+
+class FuncCallExprAST(ExprAST):
+ def __init__(self, slicc, proc_name, exprs):
+ super(FuncCallExprAST, self).__init__(slicc)
+ self.proc_name = proc_name
+ self.exprs = exprs
+
+ def __repr__(self):
+ return "[FuncCallExpr: %s %s]" % (self.proc_name, self.exprs)
+
+ def generate(self, code):
+ machine = self.state_machine
+
+ # DEBUG_EXPR is strange since it takes parameters of multiple types
+ if self.proc_name == "DEBUG_EXPR":
+ # FIXME - check for number of parameters
+ code('DEBUG_SLICC(MedPrio, "$0: ", $1)',
+ self.exprs[0].location, self.exprs[0].inline())
+
+ return self.symtab.find("void", Type)
+
+ # hack for adding comments to profileTransition
+ if self.proc_name == "APPEND_TRANSITION_COMMENT":
+ # FIXME - check for number of parameters
+ code("APPEND_TRANSITION_COMMENT($0)", self.exprs[0].inline())
+ return self.symtab.find("void", Type)
+
+ # Look up the function in the symbol table
+ func = self.symtab.find(self.proc_name, Func)
+
+ # Check the types and get the code for the parameters
+ if func is None:
+ self.error("Unrecognized function name: '%s'", self.proc_name)
+
+ if len(self.exprs) != len(func.param_types):
+ self.error("Wrong number of arguments passed to function : '%s'" +\
+ " Expected %d, got %d", self.proc_name,
+ len(func.param_types), len(self.exprs))
+
+ cvec = []
+ for expr,expected_type in zip(self.exprs, func.param_types):
+ # Check the types of the parameter
+ actual_type,param_code = expr.inline(True)
+ if actual_type != expected_type:
+ expr.error("Type mismatch: expected: %s actual: %s" % \
+ (expected_type, actual_type))
+ cvec.append(param_code)
+
+ # OK, the semantics of "trigger" here is that, ports in the
+ # machine have different priorities. We always check the first
+ # port for doable transitions. If nothing/stalled, we pick one
+ # from the next port.
+ #
+ # One thing we have to be careful as the SLICC protocol
+ # writter is : If a port have two or more transitions can be
+ # picked from in one cycle, they must be independent.
+ # Otherwise, if transition A and B mean to be executed in
+ # sequential, and A get stalled, transition B can be issued
+ # erroneously. In practice, in most case, there is only one
+ # transition should be executed in one cycle for a given
+ # port. So as most of current protocols.
+
+ if self.proc_name == "trigger":
+ code('''
+{
+ Address addr = ${{cvec[1]}};
+ TransitionResult result = doTransition(${{cvec[0]}}, ${machine}_getState(addr), addr);
+
+ if (result == TransitionResult_Valid) {
+ counter++;
+ continue; // Check the first port again
+ }
+
+ if (result == TransitionResult_ResourceStall) {
+ g_eventQueue_ptr->scheduleEvent(this, 1);
+
+ // Cannot do anything with this transition, go check next doable transition (mostly likely of next port)
+ }
+}
+''')
+ elif self.proc_name == "doubleTrigger":
+ # NOTE: Use the doubleTrigger call with extreme caution
+ # the key to double trigger is the second event triggered
+ # cannot fail becuase the first event cannot be undone
+ assert len(cvec) == 4
+ code('''
+{
+ Address addr1 = ${{cvec[1]}};
+ TransitionResult result1 =
+ doTransition(${{cvec[0]}}, ${machine}_getState(addr1), addr1);
+
+ if (result1 == TransitionResult_Valid) {
+ //this second event cannont fail because the first event
+ // already took effect
+ Address addr2 = ${{cvec[3]}};
+ TransitionResult result2 = doTransition(${{cvec[2]}}, ${machine}_getState(addr2), addr2);
+
+ // ensure the event suceeded
+ assert(result2 == TransitionResult_Valid);
+
+ counter++;
+ continue; // Check the first port again
+ }
+
+ if (result1 == TransitionResult_ResourceStall) {
+ g_eventQueue_ptr->scheduleEvent(this, 1);
+ // Cannot do anything with this transition, go check next
+ // doable transition (mostly likely of next port)
+ }
+}
+''')
+ elif self.proc_name == "error":
+ code("$0", self.exprs[0].embedError(cvec[0]))
+ elif self.proc_name == "assert":
+ error = self.exprs[0].embedError('"assert failure"')
+ code('''
+if (ASSERT_FLAG && !(${{cvec[0]}})) {
+ $error
+}
+''')
+
+ elif self.proc_name == "continueProcessing":
+ code("counter++;")
+ code("continue; // Check the first port again")
+ else:
+ # Normal function
+
+ # if the func is internal to the chip but not the machine
+ # then it can only be accessed through the chip pointer
+ internal = ""
+ if "external" not in func and not func.isInternalMachineFunc:
+ internal = "m_chip_ptr->"
+
+ params = ', '.join(str(c) for c in cvec)
+ fix = code.nofix()
+ code('(${internal}${{func.c_ident}}($params))')
+ code.fix(fix)
+
+ return func.return_type
diff --git a/src/mem/slicc/ast/FuncDeclAST.cc b/src/mem/slicc/ast/FuncDeclAST.cc
deleted file mode 100644
index 2a0905f06..000000000
--- a/src/mem/slicc/ast/FuncDeclAST.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * FuncDeclAST.C
- *
- * Description: See FuncDeclAST.hh
- *
- * $Id: FuncDeclAST.C,v 3.4 2003/08/22 18:19:34 beckmann Exp $
- *
- */
-
-#include "mem/slicc/ast/FuncDeclAST.hh"
-#include "mem/slicc/ast/FormalParamAST.hh"
-#include "mem/slicc/symbols/SymbolTable.hh"
-#include "mem/slicc/main.hh"
-
-FuncDeclAST::FuncDeclAST(TypeAST* return_type_ast_ptr,
- string* ident_ptr,
- Vector<FormalParamAST*>* formal_vec_ptr,
- PairListAST* pairs_ptr,
- StatementListAST* statement_list_ptr)
- : DeclAST(pairs_ptr)
-{
- m_return_type_ast_ptr = return_type_ast_ptr;
- m_ident_ptr = ident_ptr;
- m_formal_vec_ptr = formal_vec_ptr;
- m_statement_list_ptr = statement_list_ptr;
-}
-
-FuncDeclAST::~FuncDeclAST()
-{
- delete m_return_type_ast_ptr;
- delete m_ident_ptr;
-
- int size = m_formal_vec_ptr->size();
- for(int i=0; i<size; i++) {
- delete (*m_formal_vec_ptr)[i];
- }
- delete m_formal_vec_ptr;
- delete m_statement_list_ptr;
-}
-
-void FuncDeclAST::generate()
-{
- Vector<Type*> type_vec;
- Vector<string> param_vec;
- Type* void_type_ptr = g_sym_table.getType("void");
-
- // Generate definition code
- g_sym_table.pushFrame();
-
- // Lookup return type
- Type* return_type_ptr = m_return_type_ast_ptr->lookupType();
-
- // Generate function header
- int size = m_formal_vec_ptr->size();
- for(int i=0; i<size; i++) {
- // Lookup parameter types
- string ident;
- Type* type_ptr = (*m_formal_vec_ptr)[i]->generate(ident);
- type_vec.insertAtBottom(type_ptr);
- param_vec.insertAtBottom(ident);
- }
-
- string body;
- if (m_statement_list_ptr == NULL) {
- getPairs().add("external", "yes");
- } else {
- m_statement_list_ptr->generate(body, return_type_ptr);
- }
- g_sym_table.popFrame();
-
- StateMachine* machine_ptr = g_sym_table.getStateMachine();
- if (machine_ptr != NULL) {
- machine_ptr->addFunc(new Func(*m_ident_ptr, getLocation(), return_type_ptr, type_vec, param_vec, body, getPairs(), machine_ptr));
- } else {
- g_sym_table.newSym(new Func(*m_ident_ptr, getLocation(), return_type_ptr, type_vec, param_vec, body, getPairs(), machine_ptr));
- }
-
-}
-
-void FuncDeclAST::print(ostream& out) const
-{
- out << "[FuncDecl: " << *m_ident_ptr << "]";
-}
diff --git a/src/mem/slicc/ast/FuncDeclAST.hh b/src/mem/slicc/ast/FuncDeclAST.hh
deleted file mode 100644
index 205e71a85..000000000
--- a/src/mem/slicc/ast/FuncDeclAST.hh
+++ /dev/null
@@ -1,91 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * FuncDeclAST.hh
- *
- * Description:
- *
- * $Id: FuncDeclAST.hh,v 3.2 2003/07/10 18:08:06 milo Exp $
- *
- */
-
-#ifndef FuncDeclAST_H
-#define FuncDeclAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/DeclAST.hh"
-#include "mem/slicc/ast/TypeFieldAST.hh"
-#include "mem/slicc/ast/TypeAST.hh"
-
-class FormalParamsAST;
-
-class FuncDeclAST : public DeclAST {
-public:
- // Constructors
- FuncDeclAST(TypeAST* return_type_ptr,
- string* ident_ptr,
- Vector<FormalParamAST*>* formal_vec_ptr,
- PairListAST* pairs_ptr,
- StatementListAST* statement_list_ptr);
- // Destructor
- ~FuncDeclAST();
-
- // Public Methods
- void generate();
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- FuncDeclAST(const FuncDeclAST& obj);
- FuncDeclAST& operator=(const FuncDeclAST& obj);
-
- // Data Members (m_ prefix)
- string* m_ident_ptr;
- TypeAST* m_return_type_ast_ptr;
- Vector<FormalParamAST*>* m_formal_vec_ptr;
- StatementListAST* m_statement_list_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const FuncDeclAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const FuncDeclAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //FuncDeclAST_H
diff --git a/src/mem/slicc/ast/FuncDeclAST.py b/src/mem/slicc/ast/FuncDeclAST.py
new file mode 100644
index 000000000..980804c2a
--- /dev/null
+++ b/src/mem/slicc/ast/FuncDeclAST.py
@@ -0,0 +1,88 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.util.code_formatter import code_formatter
+
+from slicc.ast.DeclAST import DeclAST
+from slicc.symbols import Func, Type
+
+class FuncDeclAST(DeclAST):
+ def __init__(self, slicc, return_type, ident, formals, pairs, statements):
+ super(FuncDeclAST, self).__init__(slicc, pairs)
+
+ self.return_type = return_type
+ self.ident = ident
+ self.formals = formals
+ self.statements = statements
+
+ def __repr__(self):
+ return "[FuncDecl: %s]" % self.ident
+
+ def files(self, parent=None):
+ if "external" in self or self.statements is None:
+ return set()
+
+ if parent:
+ ident = "%s_%s" % (parent, self.ident)
+ else:
+ ident = self.ident
+ return set(("%s.cc" % ident,))
+
+ def generate(self):
+ types = []
+ params = []
+ void_type = self.symtab.find("void", Type)
+
+ # Generate definition code
+ self.symtab.pushFrame()
+
+ # Lookup return type
+ return_type = self.return_type.type
+
+ # Generate function header
+ for formal in self.formals:
+ # Lookup parameter types
+ type, ident = formal.generate()
+ types.append(type)
+ params.append(ident)
+
+ body = code_formatter()
+ if self.statements is None:
+ self["external"] = "yes"
+ else:
+ rtype = self.statements.generate(body, return_type)
+
+ self.symtab.popFrame()
+
+ machine = self.state_machine
+ func = Func(self.symtab, self.ident, self.location, return_type,
+ types, params, str(body), self.pairs, machine)
+
+ if machine is not None:
+ machine.addFunc(func)
+ else:
+ self.symtab.newSymbol(func)
diff --git a/src/mem/slicc/ast/IfStatementAST.cc b/src/mem/slicc/ast/IfStatementAST.cc
deleted file mode 100644
index 40942a58d..000000000
--- a/src/mem/slicc/ast/IfStatementAST.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * IfStatementAST.C
- *
- * Description: See IfStatementAST.hh
- *
- * $Id$
- *
- */
-
-#include "mem/slicc/ast/IfStatementAST.hh"
-
-IfStatementAST::IfStatementAST(ExprAST* cond_ptr,
- StatementListAST* then_ptr,
- StatementListAST* else_ptr)
- : StatementAST()
-{
- assert(cond_ptr != NULL);
- assert(then_ptr != NULL);
- m_cond_ptr = cond_ptr;
- m_then_ptr = then_ptr;
- m_else_ptr = else_ptr;
-}
-
-IfStatementAST::~IfStatementAST()
-{
- delete m_cond_ptr;
- delete m_then_ptr;
- delete m_else_ptr;
-}
-
-
-void IfStatementAST::generate(string& code, Type* return_type_ptr) const
-{
- Type* type_ptr;
-
- // Conditional
- code += indent_str() + "if (";
- type_ptr = m_cond_ptr->generate(code);
- if (type_ptr != g_sym_table.getType("bool")) {
- m_cond_ptr->error("Condition of if statement must be boolean, type was '" + type_ptr->toString() + "'");
- }
- code += ") {\n";
- // Then part
- inc_indent();
- m_then_ptr->generate(code, return_type_ptr);
- dec_indent();
- // Else part
- if (m_else_ptr != NULL) {
- code += indent_str() + "} else {\n";
- inc_indent();
- m_else_ptr->generate(code, return_type_ptr);
- dec_indent();
- }
- code += indent_str() + "}\n"; // End scope
-}
-
-void IfStatementAST::findResources(Map<Var*, string>& resource_list) const
-{
- // Take a worse case look at both paths
- m_then_ptr->findResources(resource_list);
- if (m_else_ptr != NULL) {
- m_else_ptr->findResources(resource_list);
- }
-}
-
-void IfStatementAST::print(ostream& out) const
-{
- out << "[IfStatement: " << *m_cond_ptr << *m_then_ptr << *m_else_ptr << "]";
-}
diff --git a/src/mem/slicc/ast/IfStatementAST.hh b/src/mem/slicc/ast/IfStatementAST.hh
deleted file mode 100644
index 2c168913a..000000000
--- a/src/mem/slicc/ast/IfStatementAST.hh
+++ /dev/null
@@ -1,89 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * IfStatementAST.hh
- *
- * Description:
- *
- * $Id$
- *
- */
-
-#ifndef IFSTATEMENTAST_H
-#define IFSTATEMENTAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/ExprAST.hh"
-#include "mem/slicc/ast/StatementAST.hh"
-#include "mem/slicc/ast/StatementListAST.hh"
-
-
-class IfStatementAST : public StatementAST {
-public:
- // Constructors
- IfStatementAST(ExprAST* cond_ptr,
- StatementListAST* then_ptr,
- StatementListAST* else_ptr);
-
- // Destructor
- ~IfStatementAST();
-
- // Public Methods
- void generate(string& code, Type* return_type_ptr) const;
- void findResources(Map<Var*, string>& resource_list) const;
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- IfStatementAST(const IfStatementAST& obj);
- IfStatementAST& operator=(const IfStatementAST& obj);
-
- // Data Members (m_ prefix)
- ExprAST* m_cond_ptr;
- StatementListAST* m_then_ptr;
- StatementListAST* m_else_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const IfStatementAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const IfStatementAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //IFSTATEMENTAST_H
diff --git a/src/mem/slicc/ast/IfStatementAST.py b/src/mem/slicc/ast/IfStatementAST.py
new file mode 100644
index 000000000..788876fd1
--- /dev/null
+++ b/src/mem/slicc/ast/IfStatementAST.py
@@ -0,0 +1,74 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.util import code_formatter
+
+from slicc.ast.StatementAST import StatementAST
+from slicc.symbols import Type
+
+class IfStatementAST(StatementAST):
+ def __init__(self, slicc, cond, then, else_):
+ super(IfStatementAST, self).__init__(slicc)
+
+ assert cond is not None
+ assert then is not None
+
+ self.cond = cond
+ self.then = then
+ self.else_ = else_
+
+ def __repr__(self):
+ return "[IfStatement: %r%r%r]" % (self.cond, self.then, self.else_)
+
+ def generate(self, code, return_type):
+ cond_code = code_formatter()
+ cond_type = self.cond.generate(cond_code)
+
+ if cond_type != self.symtab.find("bool", Type):
+ self.cond.error("Condition of if stmt must be bool, type was '%s'",
+ ctype)
+
+ # Conditional
+ code.indent()
+ code('if ($cond_code) {')
+ # Then part
+ code.indent()
+ self.then.generate(code, return_type)
+ code.dedent()
+ # Else part
+ if self.else_:
+ code('} else {')
+ code.indent()
+ self.else_.generate(code, return_type)
+ code.dedent()
+ code('}') # End scope
+
+ def findResources(self, resources):
+ # Take a worse case look at both paths
+ self.then.findResources(resources)
+ if self.else_ is not None:
+ self.else_.findResources(resources)
diff --git a/src/mem/slicc/ast/InPortDeclAST.cc b/src/mem/slicc/ast/InPortDeclAST.cc
deleted file mode 100644
index f62af9921..000000000
--- a/src/mem/slicc/ast/InPortDeclAST.cc
+++ /dev/null
@@ -1,149 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * InPortDeclAST.C
- *
- * Description: See InPortDeclAST.hh
- *
- * $Id$
- *
- */
-
-#include "mem/slicc/ast/InPortDeclAST.hh"
-#include "mem/slicc/symbols/SymbolTable.hh"
-#include "mem/slicc/symbols/Var.hh"
-
-InPortDeclAST::InPortDeclAST(string* ident_ptr,
- TypeAST* msg_type_ptr,
- ExprAST* var_expr_ptr,
- PairListAST* pairs_ptr,
- StatementListAST* statement_list_ptr)
- : DeclAST(pairs_ptr)
-{
- m_ident_ptr = ident_ptr;
- m_msg_type_ptr = msg_type_ptr;
- m_var_expr_ptr = var_expr_ptr;
- m_statement_list_ptr = statement_list_ptr;
- m_queue_type_ptr = new TypeAST(new string("InPort"));
-}
-
-InPortDeclAST::~InPortDeclAST()
-{
- delete m_ident_ptr;
- delete m_msg_type_ptr;
- delete m_var_expr_ptr;
- delete m_statement_list_ptr;
- delete m_queue_type_ptr;
-}
-
-void InPortDeclAST::generate()
-{
- string code;
- Type* queue_type_ptr = m_var_expr_ptr->generate(code);
- if (!queue_type_ptr->isInPort()) {
- error("Inport queues must be of a type that has the 'inport' attribute. The type '" +
- queue_type_ptr->toString() + "' does not have this attribute.");
- }
-
- Type* type_ptr = m_queue_type_ptr->lookupType();
- Var* in_port_ptr = new Var(*m_ident_ptr, getLocation(), type_ptr, code, getPairs());
- g_sym_table.newSym(in_port_ptr);
-
- g_sym_table.pushFrame();
- Vector<Type*> param_type_vec;
-
- // Check for Event
- type_ptr = g_sym_table.getType("Event");
- if (type_ptr == NULL) {
- error("in_port declarations require 'Event' enumeration to be defined");
- }
- param_type_vec.insertAtBottom(type_ptr);
-
- // Check for Address
- type_ptr = g_sym_table.getType("Address");
- if (type_ptr == NULL) {
- error("in_port declarations require 'Address' type to be defined");
- }
- param_type_vec.insertAtBottom(type_ptr);
-
- // Add the trigger method - FIXME, this is a bit dirty
- Map<string, string> pairs;
- pairs.add("external", "yes");
- Vector<string> string_vec;
- g_sym_table.newSym(new Func("trigger", getLocation(), g_sym_table.getType("void"), param_type_vec, string_vec, string(""), pairs, NULL));
-
- // Check for Event2
- type_ptr = g_sym_table.getType("Event");
- if (type_ptr == NULL) {
- error("in_port declarations require 'Event' enumeration to be defined");
- }
- param_type_vec.insertAtBottom(type_ptr);
-
- // Check for Address2
- type_ptr = g_sym_table.getType("Address");
- if (type_ptr == NULL) {
- error("in_port declarations require 'Address' type to be defined");
- }
- param_type_vec.insertAtBottom(type_ptr);
-
- // Add the doubleTrigger method - this hack supports tiggering two simulateous events
- // The key is that the second transistion cannot fail because the first event cannot be undone
- // therefore you must do some checks before calling double trigger to ensure that won't happen
- g_sym_table.newSym(new Func("doubleTrigger", getLocation(), g_sym_table.getType("void"), param_type_vec, string_vec, string(""), pairs, NULL));
-
- // Add the continueProcessing method - this hack supports messages that don't trigger events
- Vector<Type*> empty_param_type_vec;
- Vector<string> empty_string_vec;
- g_sym_table.newSym(new Func("continueProcessing", getLocation(), g_sym_table.getType("void"), empty_param_type_vec, empty_string_vec, string(""), pairs, NULL));
-
- if (m_statement_list_ptr != NULL) {
- inc_indent();
- inc_indent();
- string code;
- m_statement_list_ptr->generate(code, NULL);
- in_port_ptr->addPair("c_code_in_port", code);
- dec_indent();
- dec_indent();
- }
- g_sym_table.popFrame();
-
- // Add port to state machine
- StateMachine* machine_ptr = g_sym_table.getStateMachine();
- if (machine_ptr == NULL) {
- error("InPort declaration not part of a machine.");
- }
- machine_ptr->addInPort(in_port_ptr);
-}
-
-
-void InPortDeclAST::print(ostream& out) const
-{
- out << "[InPortDecl: " << *m_ident_ptr << "]";
-}
diff --git a/src/mem/slicc/ast/InPortDeclAST.hh b/src/mem/slicc/ast/InPortDeclAST.hh
deleted file mode 100644
index e6295a6e2..000000000
--- a/src/mem/slicc/ast/InPortDeclAST.hh
+++ /dev/null
@@ -1,91 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * InPortDeclAST.hh
- *
- * Description:
- *
- * $Id: InPortDeclAST.hh,v 3.2 2003/07/10 18:08:06 milo Exp $
- *
- */
-
-#ifndef InPortDeclAST_H
-#define InPortDeclAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/DeclAST.hh"
-#include "mem/slicc/ast/StatementListAST.hh"
-#include "mem/slicc/ast/VarExprAST.hh"
-
-class InPortDeclAST : public DeclAST {
-public:
- // Constructors
- InPortDeclAST(string* ident_ptr,
- TypeAST* msg_type_ptr,
- ExprAST* var_expr_ptr,
- PairListAST* pairs_ptr,
- StatementListAST* statement_list_ptr);
-
- // Destructor
- ~InPortDeclAST();
-
- // Public Methods
- void generate();
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- InPortDeclAST(const InPortDeclAST& obj);
- InPortDeclAST& operator=(const InPortDeclAST& obj);
-
- // Data Members (m_ prefix)
- string* m_ident_ptr;
- TypeAST* m_msg_type_ptr;
- ExprAST* m_var_expr_ptr;
- StatementListAST* m_statement_list_ptr;
- TypeAST* m_queue_type_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const InPortDeclAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const InPortDeclAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //InPortDeclAST_H
diff --git a/src/mem/slicc/ast/InPortDeclAST.py b/src/mem/slicc/ast/InPortDeclAST.py
new file mode 100644
index 000000000..3dde24557
--- /dev/null
+++ b/src/mem/slicc/ast/InPortDeclAST.py
@@ -0,0 +1,130 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.util import code_formatter
+
+from slicc.ast.DeclAST import DeclAST
+from slicc.ast.TypeAST import TypeAST
+from slicc.symbols import Func, Type, Var
+
+class InPortDeclAST(DeclAST):
+ def __init__(self, slicc, ident, msg_type, var_expr, pairs, statements):
+ super(InPortDeclAST, self).__init__(slicc, pairs)
+
+ self.ident = ident
+ self.msg_type = msg_type
+ self.var_expr = var_expr
+ self.statements = statements
+ self.queue_type = TypeAST(slicc, "InPort")
+
+ def __repr__(self):
+ return "[InPortDecl: %s]" % self.ident
+
+ def generate(self):
+ symtab = self.symtab
+ void_type = symtab.find("void", Type)
+
+ code = code_formatter()
+ queue_type = self.var_expr.generate(code)
+ if not queue_type.isInPort:
+ self.error("The inport queue's type must have the 'inport' " + \
+ "attribute. Type '%s' does not have this attribute.",
+ queue_type)
+
+ type = self.queue_type.type
+ in_port = Var(self.symtab, self.ident, self.location, type, str(code),
+ self.pairs)
+ symtab.newSymbol(in_port)
+
+ symtab.pushFrame()
+ param_types = []
+
+ # Check for Event
+ type = symtab.find("Event", Type)
+ if type is None:
+ self.error("in_port decls require 'Event' enumeration defined")
+ param_types.append(type)
+
+ # Check for Address
+ type = symtab.find("Address", Type)
+ if type is None:
+ self.error("in_port decls require 'Address' type to be defined")
+
+ param_types.append(type)
+
+ # Add the trigger method - FIXME, this is a bit dirty
+ pairs = { "external" : "yes" }
+ func = Func(self.symtab, "trigger", self.location, void_type,
+ param_types, [], "", pairs, None)
+ symtab.newSymbol(func)
+
+ param_types = []
+ # Check for Event2
+ type = symtab.find("Event", Type)
+ if type is None:
+ self.error("in_port decls require 'Event' enumeration")
+
+ param_types.append(type)
+
+ # Check for Address2
+ type = symtab.find("Address", Type)
+ if type is None:
+ self.error("in_port decls require 'Address' type to be defined")
+
+ param_types.append(type)
+
+ # Add the doubleTrigger method - this hack supports tiggering
+ # two simulateous events
+ #
+ # The key is that the second transistion cannot fail because
+ # the first event cannot be undone therefore you must do some
+ # checks before calling double trigger to ensure that won't
+ # happen
+ func = Func(self.symtab, "doubleTrigger", self.location, void_type,
+ param_types, [], "", pairs, None)
+ symtab.newSymbol(func)
+
+ # Add the continueProcessing method - this hack supports
+ # messages that don't trigger events
+ func = Func(self.symtab, "continueProcessing", self.location,
+ void_type, [], [], "", pairs, None)
+ symtab.newSymbol(func)
+
+ if self.statements is not None:
+ rcode = code_formatter()
+ rcode.indent()
+ rcode.indent()
+ self.statements.generate(rcode, None)
+ in_port["c_code_in_port"] = str(rcode)
+ symtab.popFrame()
+
+ # Add port to state machine
+ machine = symtab.state_machine
+ if machine is None:
+ self.error("InPort declaration not part of a machine.")
+
+ machine.addInPort(in_port)
diff --git a/src/mem/slicc/ast/InfixOperatorExprAST.cc b/src/mem/slicc/ast/InfixOperatorExprAST.cc
deleted file mode 100644
index 40719fc66..000000000
--- a/src/mem/slicc/ast/InfixOperatorExprAST.cc
+++ /dev/null
@@ -1,121 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * InfixOperatorExprAST.C
- *
- * Description: See InfixOperatorExprAST.hh
- *
- * $Id: InfixOperatorExprAST.C,v 3.2 2004/01/31 20:46:15 milo Exp $
- *
- */
-
-#include "mem/slicc/ast/InfixOperatorExprAST.hh"
-
-InfixOperatorExprAST::InfixOperatorExprAST(ExprAST* left_ptr,
- string* op_ptr,
- ExprAST* right_ptr)
- : ExprAST()
-{
- m_left_ptr = left_ptr;
- m_op_ptr = op_ptr;
- m_right_ptr = right_ptr;
-}
-
-InfixOperatorExprAST::~InfixOperatorExprAST()
-{
- delete m_left_ptr;
- delete m_op_ptr;
- delete m_right_ptr;
-}
-
-Type* InfixOperatorExprAST::generate(string& code) const
-{
- code += "(";
- Type* left_type_ptr = m_left_ptr->generate(code);
- code += " " + *m_op_ptr + " ";
- Type* right_type_ptr = m_right_ptr->generate(code);
- code += ")";
-
- string inputs, output;
- // Figure out what the input and output types should be
- if ((*m_op_ptr == "==" ||
- *m_op_ptr == "!=")) {
- output = "bool";
- if (left_type_ptr != right_type_ptr) {
- error("Type mismatch: left & right operand of operator '" + *m_op_ptr +
- "' must be the same type." +
- "left: '" + left_type_ptr->toString() +
- "', right: '" + right_type_ptr->toString() + "'");
- }
- } else {
- if ((*m_op_ptr == "&&" ||
- *m_op_ptr == "||")) {
- // boolean inputs and output
- inputs = "bool";
- output = "bool";
- } else if ((*m_op_ptr == "==" ||
- *m_op_ptr == "!=" ||
- *m_op_ptr == ">=" ||
- *m_op_ptr == "<=" ||
- *m_op_ptr == ">" ||
- *m_op_ptr == "<")) {
- // Integer inputs, boolean output
- inputs = "int";
- output = "bool";
- } else {
- // integer inputs and output
- inputs = "int";
- output = "int";
- }
-
- Type* inputs_type = g_sym_table.getType(inputs);
-
- if (inputs_type != left_type_ptr) {
- m_left_ptr->error("Type mismatch: left operand of operator '" + *m_op_ptr +
- "' expects input type '" + inputs + "', actual was " + left_type_ptr->toString() + "'");
- }
-
- if (inputs_type != right_type_ptr) {
- m_right_ptr->error("Type mismatch: right operand of operator '" + *m_op_ptr +
- "' expects input type '" + inputs + "', actual was '" + right_type_ptr->toString() + "'");
- }
- }
-
- // All is well
- Type* output_type = g_sym_table.getType(output);
- return output_type;
-}
-
-
-void InfixOperatorExprAST::print(ostream& out) const
-{
- out << "[InfixExpr: " << *m_left_ptr
- << *m_op_ptr << *m_right_ptr << "]";
-}
diff --git a/src/mem/slicc/ast/InfixOperatorExprAST.py b/src/mem/slicc/ast/InfixOperatorExprAST.py
new file mode 100644
index 000000000..c4fb4a4db
--- /dev/null
+++ b/src/mem/slicc/ast/InfixOperatorExprAST.py
@@ -0,0 +1,89 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.util import code_formatter
+
+from slicc.ast.ExprAST import ExprAST
+from slicc.symbols import Type
+
+class InfixOperatorExprAST(ExprAST):
+ def __init__(self, slicc, left, op, right):
+ super(InfixOperatorExprAST, self).__init__(slicc)
+
+ self.left = left
+ self.op = op
+ self.right = right
+
+ def __repr__(self):
+ return "[InfixExpr: %r %s %r]" % (self.left, self.op, self.right)
+
+ def generate(self, code):
+ lcode = code_formatter()
+ rcode = code_formatter()
+
+ ltype = self.left.generate(lcode)
+ rtype = self.right.generate(rcode)
+
+ # Figure out what the input and output types should be
+ if self.op in ("==", "!="):
+ output = "bool"
+ if (ltype != rtype):
+ self.error("Type mismatch: left and right operands of " +
+ "operator '%s' must be the same type. " +
+ "left: '%s', right: '%s'",
+ self.op, ltype, rtype)
+ else:
+ if self.op in ("&&", "||"):
+ # boolean inputs and output
+ inputs = "bool"
+ output = "bool"
+ elif self.op in ("==", "!=", ">=", "<=", ">", "<"):
+ # Integer inputs, boolean output
+ inputs = "int"
+ output = "bool"
+ else:
+ # integer inputs and output
+ inputs = "int"
+ output = "int"
+
+ inputs_type = self.symtab.find(inputs, Type)
+
+ if inputs_type != ltype:
+ self.left.error("Type mismatch: left operand of operator " +
+ "'%s' expects type '%s', actual was '%s'",
+ self.op, inputs, ltype)
+
+ if inputs_type != rtype:
+ self.right.error("Type mismatch: right operand of operator " +
+ "'%s' expects type '%s', actual was '%s'",
+ self.op, inputs, rtype)
+
+ # All is well
+ fix = code.nofix()
+ code("($lcode ${{self.op}} $rcode)")
+ code.fix(fix)
+ return self.symtab.find(output, Type)
diff --git a/src/mem/slicc/ast/LiteralExprAST.py b/src/mem/slicc/ast/LiteralExprAST.py
new file mode 100644
index 000000000..773e8f35c
--- /dev/null
+++ b/src/mem/slicc/ast/LiteralExprAST.py
@@ -0,0 +1,55 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.ExprAST import ExprAST
+from slicc.symbols import Type
+
+class LiteralExprAST(ExprAST):
+ def __init__(self, slicc, literal, type):
+ super(LiteralExprAST, self).__init__(slicc)
+ self.literal = literal
+ self.type = type
+
+ def __repr__(self):
+ return "[Literal: %s]" % self.literal
+
+ def generate(self, code):
+ fix = code.nofix()
+ if self.type == "string":
+ code('("${{self.literal}}")')
+ elif self.type == "bool":
+ code('(${{str(self.literal).lower()}})')
+ else:
+ code('(${{self.literal}})')
+ code.fix(fix)
+
+ type = self.symtab.find(self.type, Type)
+ if type is None:
+ # Can't find the type
+ self.error("Internal: can't primitive type '%s'" % self.type)
+
+ return type
diff --git a/src/mem/slicc/ast/Location.cc b/src/mem/slicc/ast/Location.cc
deleted file mode 100644
index fd224fe2f..000000000
--- a/src/mem/slicc/ast/Location.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Location.C
- *
- * Description: See Location.hh
- *
- * $Id: Location.C,v 3.3 2004/05/30 22:19:02 kmoore Exp $
- *
- */
-
-#include "mem/slicc/ast/Location.hh"
-
-int g_line_number = 0;
-string &g_file_name()
-{
- static string the_string;
- return the_string;
-}
-
-Location::Location()
-{
- m_file_name = g_file_name();
- m_line_number = g_line_number;
-
- ostringstream sstr;
- sstr << getLineNumber();
- m_line_number_str = sstr.str();
-}
-
-void Location::error(string err_msg) const
-{
- cerr << endl;
- cerr << toString() << ": Error: " << err_msg << endl;
- exit(1);
-}
-
-string Location::embedError(string err_msg) const
-{
- string code;
- code += "cerr << \"Runtime Error at ";
- code += toString() + ", Ruby Time: \" << ";
- code += "g_eventQueue_ptr->getTime() << \": \" << ";
- code += err_msg;
- code += " << \", PID: \" << getpid() << endl;\n";
- code += "char c; cerr << \"press return to continue.\" << endl; cin.get(c); abort();\n";
-
- return code;
-}
-
-void Location::warning(string err_msg) const
-{
- cerr << toString() << ": Warning: "
- << err_msg << endl;
-}
-
-string Location::toString() const
-{
- return m_file_name + ":" + m_line_number_str;
-}
diff --git a/src/mem/slicc/ast/Location.hh b/src/mem/slicc/ast/Location.hh
deleted file mode 100644
index c9e20418e..000000000
--- a/src/mem/slicc/ast/Location.hh
+++ /dev/null
@@ -1,93 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Location.hh
- *
- * Description:
- *
- * $Id: Location.hh,v 3.1 2001/12/12 01:00:20 milo Exp $
- *
- */
-
-#ifndef LOCATION_H
-#define LOCATION_H
-
-#include "mem/slicc/slicc_global.hh"
-
-extern int g_line_number;
-extern string &g_file_name();
-
-class Location {
-public:
- // Constructors
- Location();
-
- // Destructor
- //~Location();
-
- // Public Methods
-
- void print(ostream& out) const;
- void error(string err_msg) const;
- string embedError(string err_msg) const;
- void warning(string err_msg) const;
- string toString() const;
-
-private:
- // Private Methods
- const string& getFileName() const { return m_file_name; }
- int getLineNumber() const { return m_line_number; }
- string getLineNumberStr() const { return m_line_number_str; }
-
- // Private copy constructor and assignment operator
- //Location(const Location& obj);
- //Location& operator=(const Location& obj);
-
- // Data Members (m_ prefix)
- string m_file_name;
- int m_line_number;
- string m_line_number_str;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const Location& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const Location& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //LOCATION_H
diff --git a/src/mem/slicc/ast/MachineAST.cc b/src/mem/slicc/ast/MachineAST.cc
deleted file mode 100644
index ae8026458..000000000
--- a/src/mem/slicc/ast/MachineAST.cc
+++ /dev/null
@@ -1,99 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * MachineAST.cc
- *
- * Description: See MachineAST.hh
- *
- * $Id: MachineAST.cc,v 3.1 2003/03/17 01:54:25 xu Exp $
- *
- */
-
-#include "mem/slicc/ast/MachineAST.hh"
-#include "mem/slicc/ast/FormalParamAST.hh"
-#include "mem/slicc/symbols/SymbolTable.hh"
-
-MachineAST::MachineAST(string* ident_ptr,
- PairListAST* pairs_ptr,
- Vector<FormalParamAST*>* config_parameters,
- DeclListAST* decl_list_ptr)
-
- : DeclAST(pairs_ptr)
-{
- m_ident_ptr = ident_ptr;
- m_pairs_ptr = pairs_ptr;
- m_config_parameters = config_parameters;
- m_decl_list_ptr = decl_list_ptr;
-}
-
-MachineAST::~MachineAST()
-{
- delete m_ident_ptr;
- delete m_pairs_ptr;
- delete m_decl_list_ptr;
-}
-
-void MachineAST::generate()
-{
- StateMachine* machine_ptr;
-
- // Make a new frame
- g_sym_table.pushFrame();
-
- // Create a new machine
- machine_ptr = new StateMachine(*m_ident_ptr, getLocation(), getPairs(), m_config_parameters);
- g_sym_table.newCurrentMachine(machine_ptr);
-
- // Generate code for all the internal decls
- m_decl_list_ptr->generate();
-
- // Build the transition table
- machine_ptr->buildTable();
-
- // Pop the frame
- g_sym_table.popFrame();
-}
-
-void MachineAST::findMachines()
-{
- // Add to MachineType enumeration
- Type* type_ptr = g_sym_table.getType("MachineType");
- if (!type_ptr->enumAdd(*m_ident_ptr, m_pairs_ptr->getPairs())) {
- error("Duplicate machine name: " + type_ptr->toString() + ":" + *m_ident_ptr);
- }
-
- // Generate code for all the internal decls
- m_decl_list_ptr->findMachines();
-}
-
-void MachineAST::print(ostream& out) const
-{
- out << "[Machine: " << *m_ident_ptr << "]";
-}
diff --git a/src/mem/slicc/ast/MachineAST.hh b/src/mem/slicc/ast/MachineAST.hh
deleted file mode 100644
index 5d1bc2a1c..000000000
--- a/src/mem/slicc/ast/MachineAST.hh
+++ /dev/null
@@ -1,93 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * ActionDeclAST.hh
- *
- * Description:
- *
- * $Id: MachineAST.hh,v 3.2 2003/07/10 18:08:06 milo Exp $
- *
- */
-
-#ifndef MachineAST_H
-#define MachineAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/DeclAST.hh"
-#include "mem/slicc/ast/DeclListAST.hh"
-#include "mem/slicc/ast/TypeFieldAST.hh"
-#include "mem/slicc/symbols/StateMachine.hh"
-
-class FormalParamAST;
-
-class MachineAST : public DeclAST {
-public:
- // Constructors
- MachineAST(string* ident_ptr,
- PairListAST* pairs_ptr,
- Vector<FormalParamAST*>* config_parameters,
- DeclListAST* decl_list_ptr);
-
- // Destructor
- ~MachineAST();
-
- // Public Methods
- void print(ostream& out) const;
- void generate();
- void findMachines();
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- MachineAST(const MachineAST& obj);
- MachineAST& operator=(const MachineAST& obj);
-
- // Data Members (m_ prefix)
- Vector<FormalParamAST*>* m_config_parameters;
- string* m_ident_ptr;
- DeclListAST* m_decl_list_ptr;
- PairListAST* m_pairs_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const MachineAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const MachineAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //MachineAST_H
diff --git a/src/mem/slicc/ast/MachineAST.py b/src/mem/slicc/ast/MachineAST.py
new file mode 100644
index 000000000..ee75b6d6a
--- /dev/null
+++ b/src/mem/slicc/ast/MachineAST.py
@@ -0,0 +1,81 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.DeclAST import DeclAST
+from slicc.symbols import StateMachine, Type
+
+class MachineAST(DeclAST):
+ def __init__(self, slicc, ident, pairs_ast, config_parameters, decls):
+ super(MachineAST, self).__init__(slicc, pairs_ast)
+
+ self.ident = ident
+ self.pairs_ast = pairs_ast
+ self.config_parameters = config_parameters
+ self.decls = decls
+
+ def __repr__(self):
+ return "[Machine: %r]" % self.ident
+
+ def files(self, parent=None):
+ s = set(('%s_Controller.cc' % self.ident,
+ '%s_Controller.hh' % self.ident,
+ '%s_Profiler.cc' % self.ident,
+ '%s_Profiler.hh' % self.ident,
+ '%s_Transitions.cc' % self.ident,
+ '%s_Wakeup.cc' % self.ident))
+
+ s |= self.decls.files(self.ident)
+ return s
+
+ def generate(self):
+ # Make a new frame
+ self.symtab.pushFrame()
+
+ # Create a new machine
+ machine = StateMachine(self.symtab, self.ident, self.location,
+ self.pairs, self.config_parameters)
+
+ self.symtab.newCurrentMachine(machine)
+
+ # Generate code for all the internal decls
+ self.decls.generate()
+
+ # Build the transition table
+ machine.buildTable()
+
+ # Pop the frame
+ self.symtab.popFrame()
+
+ def findMachines(self):
+ # Add to MachineType enumeration
+ machine_type = self.symtab.find("MachineType", Type)
+ if not machine_type.enumAdd(self.ident, self.pairs_ast.pairs):
+ self.error("Duplicate machine name: %s:%s" % (machine_type,
+ self.ident))
+
+ # Generate code for all the internal decls
+ self.decls.findMachines()
diff --git a/src/mem/slicc/ast/MemberExprAST.cc b/src/mem/slicc/ast/MemberExprAST.cc
deleted file mode 100644
index 1bcfdc7f1..000000000
--- a/src/mem/slicc/ast/MemberExprAST.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * FieldExprAST.C
- *
- * Description: See FieldExprAST.hh
- *
- * $Id$
- *
- */
-
-#include "mem/slicc/ast/MemberExprAST.hh"
-
-MemberExprAST::MemberExprAST(ExprAST* expr_ast_ptr, string* field_ptr)
- : ExprAST()
-{
- m_expr_ast_ptr = expr_ast_ptr;
- m_field_ptr = field_ptr;
-}
-
-MemberExprAST::~MemberExprAST()
-{
- delete m_expr_ast_ptr;
- delete m_field_ptr;
-}
-
-Type* MemberExprAST::generate(string& code) const
-{
- code += "(";
- Type* type_ptr = m_expr_ast_ptr->generate(code);
- code += ").m_" + (*m_field_ptr);
-
- // Verify that this is a valid field name for this type
- if (!type_ptr->dataMemberExist(*m_field_ptr)) {
- error("Invalid object field: Type '" + type_ptr->toString() + "' does not have data member " + *m_field_ptr);
- }
-
- // Return the type of the field
- return type_ptr->dataMemberType(*m_field_ptr);
-}
-
-void MemberExprAST::print(ostream& out) const
-{
- out << "[MemberExprAST: " << *m_expr_ast_ptr << "." << *m_field_ptr << "]";
-}
diff --git a/src/mem/slicc/ast/MemberExprAST.hh b/src/mem/slicc/ast/MemberExprAST.hh
deleted file mode 100644
index 34b694882..000000000
--- a/src/mem/slicc/ast/MemberExprAST.hh
+++ /dev/null
@@ -1,83 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * MemberExprAST.hh
- *
- * Description:
- *
- * $Id: MemberExprAST.hh,v 3.1 2001/12/12 01:00:21 milo Exp $
- *
- */
-
-#ifndef MemberExprAST_H
-#define MemberExprAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/ExprAST.hh"
-
-
-class MemberExprAST : public ExprAST {
-public:
- // Constructors
- MemberExprAST(ExprAST* expr_ast_ptr, string* field_ptr);
-
- // Destructor
- ~MemberExprAST();
-
- // Public Methods
- Type* generate(string& code) const;
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- MemberExprAST(const MemberExprAST& obj);
- MemberExprAST& operator=(const MemberExprAST& obj);
-
- // Data Members (m_ prefix)
- ExprAST* m_expr_ast_ptr;
- string* m_field_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const MemberExprAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const MemberExprAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //MemberExprAST_H
diff --git a/src/mem/slicc/ast/MemberExprAST.py b/src/mem/slicc/ast/MemberExprAST.py
new file mode 100644
index 000000000..c62e28741
--- /dev/null
+++ b/src/mem/slicc/ast/MemberExprAST.py
@@ -0,0 +1,55 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.util import code_formatter
+
+from slicc.ast.ExprAST import ExprAST
+
+class MemberExprAST(ExprAST):
+ def __init__(self, slicc, expr_ast, field):
+ super(MemberExprAST, self).__init__(slicc)
+
+ self.expr_ast = expr_ast
+ self.field = field
+
+ def __repr__(self):
+ return "[MemberExprAST: %r.%r]" % (self.expr_ast, self.field)
+
+ def generate(self, code):
+ return_type, gcode = self.expr_ast.inline(True)
+ fix = code.nofix()
+ code("($gcode).m_${{self.field}}")
+ code.fix(fix)
+
+ # Verify that this is a valid field name for this type
+ if self.field not in return_type.data_members:
+ self.error("Invalid object field: " +
+ "Type '%s' does not have data member %s" % \
+ (return_type, self.field))
+
+ # Return the type of the field
+ return return_type.data_members[self.field].type
diff --git a/src/mem/slicc/ast/MethodCallExprAST.cc b/src/mem/slicc/ast/MethodCallExprAST.cc
deleted file mode 100644
index 1bfe312ff..000000000
--- a/src/mem/slicc/ast/MethodCallExprAST.cc
+++ /dev/null
@@ -1,160 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * MethodCallExprAST.cc
- *
- * Description: See MethodCallExprAST.hh
- *
- * $Id$
- *
- */
-
-#include "mem/slicc/ast/MethodCallExprAST.hh"
-
-MethodCallExprAST::MethodCallExprAST(ExprAST* obj_expr_ptr,
- string* proc_name_ptr,
- Vector<ExprAST*>* expr_vec_ptr)
- : ExprAST()
-{
- m_obj_expr_ptr = obj_expr_ptr;
- m_type_ptr = NULL;
- m_proc_name_ptr = proc_name_ptr;
- m_expr_vec_ptr = expr_vec_ptr;
-}
-
-MethodCallExprAST::MethodCallExprAST(TypeAST* type_ptr,
- string* proc_name_ptr,
- Vector<ExprAST*>* expr_vec_ptr)
- : ExprAST()
-{
- m_obj_expr_ptr = NULL;
- m_type_ptr = type_ptr;
- m_proc_name_ptr = proc_name_ptr;
- m_expr_vec_ptr = expr_vec_ptr;
-}
-
-MethodCallExprAST::~MethodCallExprAST()
-{
- delete m_obj_expr_ptr;
- delete m_type_ptr;
- delete m_proc_name_ptr;
- int size = m_expr_vec_ptr->size();
- for(int i=0; i<size; i++) {
- delete (*m_expr_vec_ptr)[i];
- }
- delete m_expr_vec_ptr;
-}
-
-Type* MethodCallExprAST::generate(string& code) const
-{
- Type* obj_type_ptr = NULL;
-
- string methodId;
- Vector <Type*> paramTypes;
-
- int actual_size = m_expr_vec_ptr->size();
- for(int i=0; i<actual_size; i++) {
- string tmp;
- Type* actual_type_ptr = (*m_expr_vec_ptr)[i]->generate(tmp);
- paramTypes.insertAtBottom(actual_type_ptr);
- }
-
- if(m_obj_expr_ptr) {
- // member method call
- string tmp;
- obj_type_ptr = m_obj_expr_ptr->generate(tmp);
- methodId = obj_type_ptr->methodId(*m_proc_name_ptr, paramTypes);
- if (obj_type_ptr->methodReturnType(methodId)->isInterface())
- code += "static_cast<" + obj_type_ptr->methodReturnType(methodId)->cIdent() + "&>";
- code += "((";
- code += tmp;
- code += ").";
- } else if (m_type_ptr) {
- // class method call
- code += "(" + m_type_ptr->toString() + "::";
- obj_type_ptr = m_type_ptr->lookupType();
- methodId = obj_type_ptr->methodId(*m_proc_name_ptr, paramTypes);
- } else {
- // impossible
- assert(0);
- }
-
- // generate code
- actual_size = m_expr_vec_ptr->size();
- code += (*m_proc_name_ptr) + "(";
- for(int i=0; i<actual_size; i++) {
- if (i != 0) {
- code += ", ";
- }
- // Check the types of the parameter
- Type* actual_type_ptr = (*m_expr_vec_ptr)[i]->generate(code);
- }
- code += "))";
-
- // Verify that this is a method of the object
- if (!obj_type_ptr->methodExist(methodId)) {
- error("Invalid method call: Type '" + obj_type_ptr->toString() + "' does not have a method '" + methodId + "'");
- }
-
- int expected_size = obj_type_ptr->methodParamType(methodId).size();
- if (actual_size != expected_size) {
- // Right number of parameters
- ostringstream err;
- err << "Wrong number of parameters for function name: '" << *m_proc_name_ptr << "'";
- err << ", expected: ";
- err << expected_size;
- err << ", actual: ";
- err << actual_size;
- error(err.str());
- }
-
- for(int i=0; i<actual_size; i++) {
- // Check the types of the parameter
- Type* actual_type_ptr = paramTypes[i];
- Type* expected_type_ptr = obj_type_ptr->methodParamType(methodId)[i];
- if (actual_type_ptr != expected_type_ptr) {
- (*m_expr_vec_ptr)[i]->error("Type mismatch: expected: " + expected_type_ptr->toString() +
- " actual: " + actual_type_ptr->toString());
- }
- }
-
- // Return the return type of the method
- return obj_type_ptr->methodReturnType(methodId);
-}
-
-void MethodCallExprAST::findResources(Map<Var*, string>& resource_list) const
-{
-
-}
-
-void MethodCallExprAST::print(ostream& out) const
-{
- out << "[MethodCallExpr: " << *m_proc_name_ptr << *m_obj_expr_ptr << " " << *m_expr_vec_ptr << "]";
-}
diff --git a/src/mem/slicc/ast/MethodCallExprAST.hh b/src/mem/slicc/ast/MethodCallExprAST.hh
deleted file mode 100644
index d248e6ba4..000000000
--- a/src/mem/slicc/ast/MethodCallExprAST.hh
+++ /dev/null
@@ -1,93 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * MethodCallExprAST.hh
- *
- * Description:
- *
- * $Id$
- *
- */
-
-#ifndef MethodCallExprAST_H
-#define MethodCallExprAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/StatementAST.hh"
-#include "mem/slicc/ast/ExprAST.hh"
-#include "mem/slicc/ast/TypeAST.hh"
-
-class MethodCallExprAST : public ExprAST {
-public:
- // Constructors
- MethodCallExprAST(ExprAST* m_obj_expr_ptr,
- string* proc_name_ptr,
- Vector<ExprAST*>* expr_vec_ptr);
-
- MethodCallExprAST(TypeAST* type_ptr,
- string* proc_name_ptr,
- Vector<ExprAST*>* expr_vec_ptr);
-
- // Destructor
- ~MethodCallExprAST();
-
- // Public Methods
- Type* generate(string& code) const;
- void findResources(Map<Var*, string>& resource_list) const;
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- MethodCallExprAST(const MethodCallExprAST& obj);
- MethodCallExprAST& operator=(const MethodCallExprAST& obj);
-
- // Data Members (m_ prefix)
- ExprAST* m_obj_expr_ptr;
- TypeAST* m_type_ptr;
- string* m_proc_name_ptr;
- Vector<ExprAST*>* m_expr_vec_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const MethodCallExprAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const MethodCallExprAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif // MethodCallExprAST_H
diff --git a/src/mem/slicc/ast/MethodCallExprAST.py b/src/mem/slicc/ast/MethodCallExprAST.py
new file mode 100644
index 000000000..3f9b250c1
--- /dev/null
+++ b/src/mem/slicc/ast/MethodCallExprAST.py
@@ -0,0 +1,130 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.util import code_formatter
+
+from slicc.ast.ExprAST import ExprAST
+
+class MethodCallExprAST(ExprAST):
+ def __init__(self, slicc, proc_name, expr_ast_vec):
+ super(MethodCallExprAST, self).__init__(slicc)
+ self.proc_name = proc_name
+ self.expr_ast_vec = expr_ast_vec
+
+ def generate(self, code):
+ tmp = code_formatter()
+ paramTypes = []
+ for expr_ast in self.expr_ast_vec:
+ return_type = expr_ast.generate(tmp)
+ paramTypes.append(return_type)
+
+ obj_type, methodId, prefix = self.generate_prefix(paramTypes)
+
+ # generate code
+ params = []
+ for expr_ast in self.expr_ast_vec:
+ return_type,tcode = expr_ast.inline(True)
+ params.append(str(tcode))
+ fix = code.nofix()
+ code("$prefix${{self.proc_name}}(${{', '.join(params)}}))")
+ code.fix(fix)
+
+ # Verify that this is a method of the object
+ if methodId not in obj_type.methods:
+ self.error("Invalid method call: Type '%s' does not have a method '%s'",
+ obj_type, methodId)
+
+ if len(self.expr_ast_vec) != \
+ len(obj_type.methods[methodId].param_types):
+ # Right number of parameters
+ self.error("Wrong number of parameters for function name: '%s', " + \
+ "expected: , actual: ", proc_name,
+ len(obj_type.methods[methodId].param_types),
+ len(self.expr_ast_vec))
+
+ for actual_type, expected_type in \
+ zip(paramTypes, obj_type.methods[methodId].param_types):
+ if actual_type != expected_type:
+ self.error("Type mismatch: expected: %s actual: %s",
+ expected_type, actual_type)
+
+ # Return the return type of the method
+ return obj_type.methods[methodId].return_type
+
+ def findResources(self, resources):
+ pass
+
+class MemberMethodCallExprAST(MethodCallExprAST):
+ def __init__(self, slicc, obj_expr_ast, proc_name, expr_ast_vec):
+ s = super(MemberMethodCallExprAST, self)
+ s.__init__(slicc, proc_name, expr_ast_vec)
+
+ self.obj_expr_ast = obj_expr_ast
+
+ def __repr__(self):
+ return "[MethodCallExpr: %r%r %r]" % (self.proc_name,
+ self.obj_expr_ast,
+ self.expr_ast_vec)
+ def generate_prefix(self, paramTypes):
+ code = code_formatter()
+
+ # member method call
+ obj_type = self.obj_expr_ast.generate(code)
+ methodId = obj_type.methodId(self.proc_name, paramTypes)
+
+ prefix = ""
+ if methodId not in obj_type.methods:
+ self.error("Invalid method call: Type '%s' does not have a method '%s'",
+ obj_type, methodId)
+ return_type = obj_type.methods[methodId].return_type
+ if return_type.isInterface:
+ prefix = "static_cast<%s &>" % return_type.c_ident
+ prefix = "%s((%s)." % (prefix, code)
+
+ return obj_type, methodId, prefix
+
+
+class ClassMethodCallExprAST(MethodCallExprAST):
+ def __init__(self, slicc, type_ast, proc_name, expr_ast_vec):
+ s = super(ClassMethodCallExprAST, self)
+ s.__init__(slicc, proc_name, expr_ast_vec)
+
+ self.type_ast = type_ast
+
+ def __repr__(self):
+ return "[MethodCallExpr: %r %r]" % (self.proc_name, self.expr_ast_vec)
+
+ def generate_prefix(self, paramTypes):
+
+ # class method call
+ prefix = "(%s::" % self.type_ast
+ obj_type = self.type_ast.type
+ methodId = obj_type.methodId(self.proc_name, paramTypes)
+
+ return obj_type, methodId, prefix
+
+__all__ = [ "MemberMethodCallExprAST", "ClassMethodCallExprAST" ]
diff --git a/src/mem/slicc/ast/NewExprAST.cc b/src/mem/slicc/ast/NewExprAST.cc
deleted file mode 100644
index 95e57192f..000000000
--- a/src/mem/slicc/ast/NewExprAST.cc
+++ /dev/null
@@ -1,9 +0,0 @@
-
-#include "mem/slicc/ast/NewExprAST.hh"
-
-Type* NewExprAST::generate(string & code) const
-{
- Type* type = m_type_ptr->lookupType();
- code += "new " + type->cIdent();
- return type;
-}
diff --git a/src/mem/slicc/ast/NewExprAST.hh b/src/mem/slicc/ast/NewExprAST.hh
deleted file mode 100644
index 375f130d6..000000000
--- a/src/mem/slicc/ast/NewExprAST.hh
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef NEWEXPRAST_H
-#define NEWEXPRAST_H
-
-#include "mem/slicc/ast/ExprAST.hh"
-#include "mem/slicc/ast/TypeAST.hh"
-#include "mem/slicc/symbols/Type.hh"
-
-class NewExprAST : public ExprAST
-{
-public:
- NewExprAST(TypeAST* type_ptr) : ExprAST() { m_type_ptr = type_ptr; }
- Type* generate(string & code) const;
- void print(ostream & out) const { out << "[NewExprAST: " << *m_type_ptr << "]"; }
- string getName() const { return m_type_ptr->toString(); }
-
-private:
- TypeAST* m_type_ptr;
-};
-
-#endif
diff --git a/src/mem/slicc/ast/NewExprAST.py b/src/mem/slicc/ast/NewExprAST.py
new file mode 100644
index 000000000..a42350768
--- /dev/null
+++ b/src/mem/slicc/ast/NewExprAST.py
@@ -0,0 +1,47 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.ExprAST import ExprAST
+
+class NewExprAST(ExprAST):
+ def __init__(self, slicc, type_ast):
+ super(NewExprAST, self).__init__(slicc)
+ self.type_ast = type_ast
+
+ def __repr__(self):
+ return "[NewExprAST: %r]" % self.type_ast
+
+ @property
+ def name(self):
+ return str(self.type_ast)
+
+ def generate(self, code):
+ type = self.type_ast.type
+ fix = code.nofix()
+ code("new ${{type.c_ident}}")
+ code.fix(fix)
+ return type
diff --git a/src/mem/slicc/ast/ObjDeclAST.cc b/src/mem/slicc/ast/ObjDeclAST.cc
deleted file mode 100644
index 3569395db..000000000
--- a/src/mem/slicc/ast/ObjDeclAST.cc
+++ /dev/null
@@ -1,137 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * ObjDeclAST.cc
- *
- * Description: See ObjDeclAST.hh
- *
- * $Id: ObjDeclAST.cc,v 3.13 2004/06/24 15:56:14 beckmann Exp $
- *
- */
-
-#include "mem/slicc/ast/ObjDeclAST.hh"
-#include "mem/slicc/symbols/SymbolTable.hh"
-#include "mem/slicc/main.hh"
-
-ObjDeclAST::ObjDeclAST(TypeAST* type_ptr,
- string* ident_ptr,
- PairListAST* pairs_ptr)
- : DeclAST(pairs_ptr)
-{
- m_type_ptr = type_ptr;
- m_ident_ptr = ident_ptr;
-}
-
-ObjDeclAST::~ObjDeclAST()
-{
- delete m_type_ptr;
- delete m_ident_ptr;
-}
-
-void ObjDeclAST::generate()
-{
-
- bool machineComponentSym = false;
-
- getPairs().add("chip_object", "yes");
-
- string c_code;
-
-
- if (getPairs().exist("hack")) {
- warning("'hack=' is now deprecated");
- }
-
- if (getPairs().exist("network")) {
- if (!getPairs().exist("virtual_network")) {
- error("Network queues require a 'virtual_network' attribute.");
- }
- }
-
- Type* type_ptr = m_type_ptr->lookupType();
- if (type_ptr->isBuffer()) {
- if (!getPairs().exist("ordered")) {
- error("Buffer object declarations require an 'ordered' attribute.");
- }
- }
-
- if (getPairs().exist("ordered")) {
- string value = getPairs().lookup("ordered");
- if (value != "true" && value != "false") {
- error("The 'ordered' attribute must be 'true' or 'false'.");
- }
- }
-
- if (getPairs().exist("random")) {
- string value = getPairs().lookup("random");
- if (value != "true" && value != "false") {
- error("The 'random' attribute must be 'true' or 'false'.");
- }
- }
-
- string machine;
- if (g_sym_table.getStateMachine() != NULL) {
- machine = g_sym_table.getStateMachine()->getIdent() + "_";
- }
-
- // FIXME : should all use accessors here to avoid public member variables
- if (*m_ident_ptr == "id") {
- c_code = "m_chip_ptr->getID()";
- } else if (*m_ident_ptr == "version") {
- c_code = "m_version";
- } else if (*m_ident_ptr == "machineID") {
- c_code = "m_machineID";
- } else {
- c_code = "(*m_" + machine + *m_ident_ptr + "_ptr)";
- // c_code = "(*(m_chip_ptr->m_" + machine + *m_ident_ptr + "_ptr))";
- // machineComponentSym = true;
- }
-
- Var* v = new Var(*m_ident_ptr, getLocation(), type_ptr, c_code,
- getPairs(), g_sym_table.getStateMachine());
-
- StateMachine* machine_ptr = g_sym_table.getStateMachine();
- if (machine_ptr != NULL) {
- machine_ptr->addObj(v);
- }// else {
- g_sym_table.newSym(v);
- //}
-
- // used to cheat-- that is, access components in other machines
- if (machineComponentSym) {
- g_sym_table.newMachComponentSym(v);
- }
-
-}
-
-void ObjDeclAST::print(ostream& out) const
-{
- out << "[ObjDecl: " << *m_ident_ptr << "]";
-}
diff --git a/src/mem/slicc/ast/ObjDeclAST.hh b/src/mem/slicc/ast/ObjDeclAST.hh
deleted file mode 100644
index 0b808f472..000000000
--- a/src/mem/slicc/ast/ObjDeclAST.hh
+++ /dev/null
@@ -1,86 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * ObjDeclAST.hh
- *
- * Description:
- *
- * $Id: ObjDeclAST.hh,v 3.2 2003/07/10 18:08:06 milo Exp $
- *
- */
-
-#ifndef ObjDeclAST_H
-#define ObjDeclAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/DeclAST.hh"
-#include "mem/slicc/ast/TypeFieldAST.hh"
-#include "mem/slicc/ast/TypeAST.hh"
-
-class ObjDeclAST : public DeclAST {
-public:
- // Constructors
- ObjDeclAST(TypeAST* type_ptr,
- string* ident_ptr,
- PairListAST* pairs_ptr);
-
- // Destructor
- ~ObjDeclAST();
-
- // Public Methods
- void generate();
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- ObjDeclAST(const ObjDeclAST& obj);
- ObjDeclAST& operator=(const ObjDeclAST& obj);
-
- // Data Members (m_ prefix)
- string* m_ident_ptr;
- TypeAST* m_type_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const ObjDeclAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const ObjDeclAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //ObjDeclAST_H
diff --git a/src/mem/slicc/ast/ObjDeclAST.py b/src/mem/slicc/ast/ObjDeclAST.py
new file mode 100644
index 000000000..8a967f7b8
--- /dev/null
+++ b/src/mem/slicc/ast/ObjDeclAST.py
@@ -0,0 +1,94 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.DeclAST import DeclAST
+from slicc.symbols import Var
+
+class ObjDeclAST(DeclAST):
+ def __init__(self, slicc, type_ast, ident, pairs):
+ super(ObjDeclAST, self).__init__(slicc, pairs)
+
+ self.type_ast = type_ast
+ self.ident = ident
+
+ def __repr__(self):
+ return "[ObjDecl: %r]" % self.ident
+
+ def generate(self):
+ machineComponentSym = False
+
+ self["chip_object"] = "yes"
+
+ if "hack" in self:
+ warning("'hack=' is now deprecated")
+
+ if "network" in self and "virtual_network" not in self:
+ self.error("Network queues require a 'virtual_network' attribute")
+
+ type = self.type_ast.type
+ if type.isBuffer and "ordered" not in self:
+ self.error("Buffer object decls require an 'ordered' attribute")
+
+ if "ordered" in self:
+ value = self["ordered"]
+
+ if value not in ("true", "false"):
+ self.error("The 'ordered' attribute is '%s' " + \
+ "must be 'true' or 'false'.", value)
+
+ if "random" in self:
+ value = self["random"]
+ if value not in ("true", "false"):
+ self.error("The 'random' attribute is '%s' " + \
+ "must be 'true' or 'false'.", value)
+
+ machine = self.symtab.state_machine
+
+ # FIXME : should all use accessors here to avoid public member
+ # variables
+ if self.ident == "id":
+ c_code = "m_chip_ptr.getID()"
+ elif self.ident == "version":
+ c_code = "m_version"
+ elif self.ident == "machineID":
+ c_code = "m_machineID"
+ elif machine:
+ c_code = "(*m_%s_%s_ptr)" % (machine.ident, self.ident)
+ else:
+ c_code = "(*m_%s_ptr)" % (self.ident)
+
+ v = Var(self.symtab, self.ident, self.location, type, c_code,
+ self.pairs, machine)
+
+ if machine:
+ machine.addObject(v)
+
+ self.symtab.newSymbol(v)
+
+ # used to cheat-- that is, access components in other machines
+ if machineComponentSym:
+ self.symtab.newMachComponentSym(v)
diff --git a/src/mem/slicc/ast/OutPortDeclAST.cc b/src/mem/slicc/ast/OutPortDeclAST.cc
deleted file mode 100644
index 56a377f23..000000000
--- a/src/mem/slicc/ast/OutPortDeclAST.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * OutPortDeclAST.C
- *
- * Description: See OutPortDeclAST.hh
- *
- * $Id: OutPortDeclAST.C,v 3.3 2004/02/02 22:37:51 milo Exp $
- *
- */
-
-#include "mem/slicc/ast/OutPortDeclAST.hh"
-#include "mem/slicc/symbols/SymbolTable.hh"
-
-OutPortDeclAST::OutPortDeclAST(string* ident_ptr,
- TypeAST* msg_type_ptr,
- ExprAST* var_expr_ptr,
- PairListAST* pairs_ptr)
- : DeclAST(pairs_ptr)
-{
- m_ident_ptr = ident_ptr;
- m_msg_type_ptr = msg_type_ptr;
- m_var_expr_ptr = var_expr_ptr;
- m_queue_type_ptr = new TypeAST(new string("OutPort"));
-}
-
-OutPortDeclAST::~OutPortDeclAST()
-{
- delete m_ident_ptr;
- delete m_msg_type_ptr;
- delete m_var_expr_ptr;
- delete m_queue_type_ptr;
-}
-
-void OutPortDeclAST::generate()
-{
- string code;
- Type* queue_type_ptr = m_var_expr_ptr->generate(code);
- if (!queue_type_ptr->isOutPort()) {
- error("Outport queues must be of a type that has the 'outport' attribute. The type '" +
- queue_type_ptr->toString() + "' does not have this attribute.");
- }
-
- Type* type_ptr = m_queue_type_ptr->lookupType();
- g_sym_table.newSym(new Var(*m_ident_ptr, getLocation(), type_ptr, code, getPairs()));
-}
-
-
-void OutPortDeclAST::print(ostream& out) const
-{
- out << "[OutPortDecl: " << *m_ident_ptr << "]";
-}
diff --git a/src/mem/slicc/ast/OutPortDeclAST.hh b/src/mem/slicc/ast/OutPortDeclAST.hh
deleted file mode 100644
index 0aa0172d3..000000000
--- a/src/mem/slicc/ast/OutPortDeclAST.hh
+++ /dev/null
@@ -1,89 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * OutPortDeclAST.hh
- *
- * Description:
- *
- * $Id: OutPortDeclAST.hh,v 3.2 2003/07/10 18:08:06 milo Exp $
- *
- */
-
-#ifndef OutPortDeclAST_H
-#define OutPortDeclAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/DeclAST.hh"
-#include "mem/slicc/ast/StatementListAST.hh"
-#include "mem/slicc/ast/VarExprAST.hh"
-
-class OutPortDeclAST : public DeclAST {
-public:
- // Constructors
- OutPortDeclAST(string* ident_ptr,
- TypeAST* msg_type_ptr,
- ExprAST* var_expr_ptr,
- PairListAST* pairs_ptr);
-
- // Destructor
- ~OutPortDeclAST();
-
- // Public Methods
- void generate();
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- OutPortDeclAST(const OutPortDeclAST& obj);
- OutPortDeclAST& operator=(const OutPortDeclAST& obj);
-
- // Data Members (m_ prefix)
- string* m_ident_ptr;
- TypeAST* m_msg_type_ptr;
- TypeAST* m_queue_type_ptr;
- ExprAST* m_var_expr_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const OutPortDeclAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const OutPortDeclAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //OutPortDeclAST_H
diff --git a/src/mem/slicc/ast/OutPortDeclAST.py b/src/mem/slicc/ast/OutPortDeclAST.py
new file mode 100644
index 000000000..e6ef31928
--- /dev/null
+++ b/src/mem/slicc/ast/OutPortDeclAST.py
@@ -0,0 +1,57 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.util import code_formatter
+
+from slicc.ast.DeclAST import DeclAST
+from slicc.ast.TypeAST import TypeAST
+from slicc.symbols import Var
+
+class OutPortDeclAST(DeclAST):
+ def __init__(self, slicc, ident, msg_type, var_expr, pairs):
+ super(OutPortDeclAST, self).__init__(slicc, pairs)
+
+ self.ident = ident
+ self.msg_type = msg_type
+ self.var_expr = var_expr
+ self.queue_type = TypeAST(slicc, "OutPort")
+
+ def __repr__(self):
+ return "[OutPortDecl: %r]" % self.ident
+
+ def generate(self):
+ code = code_formatter(newlines=False)
+
+ queue_type = self.var_expr.generate(code)
+ if not queue_type.isOutPort:
+ self.error("The outport queue's type must have the 'outport' " +
+ "attribute. Type '%s' does not have this attribute.",
+ (queue_type))
+
+ var = Var(self.symtab, self.ident, self.location, self.queue_type.type,
+ str(code), self.pairs)
+ self.symtab.newSymbol(var)
diff --git a/src/mem/slicc/ast/PairAST.hh b/src/mem/slicc/ast/PairAST.hh
deleted file mode 100644
index d1bb99b93..000000000
--- a/src/mem/slicc/ast/PairAST.hh
+++ /dev/null
@@ -1,86 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * PairAST.hh
- *
- * Description:
- *
- * $Id: PairAST.hh,v 3.1 2001/12/12 01:00:24 milo Exp $
- *
- */
-
-#ifndef PAIRAST_H
-#define PAIRAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/AST.hh"
-
-class PairAST : public AST {
-public:
- // Constructors
- PairAST(string* key_ptr, string* value_ptr);
- PairAST(string key, string* value_ptr);
- PairAST(string key, string value);
-
- // Destructor
- ~PairAST();
-
- // Public Methods
- string key() const { return *m_key_ptr; }
- string value() const { return *m_value_ptr; }
-
- virtual void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- // PairAST(const PairAST& obj);
- // PairAST& operator=(const PairAST& obj);
-
- // Data Members (m_ prefix)
- string* m_key_ptr;
- string* m_value_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const PairAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const PairAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //PAIRAST_H
diff --git a/src/mem/slicc/ast/PairAST.py b/src/mem/slicc/ast/PairAST.py
new file mode 100644
index 000000000..347f4d361
--- /dev/null
+++ b/src/mem/slicc/ast/PairAST.py
@@ -0,0 +1,36 @@
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.AST import AST
+
+class PairAST(AST):
+ def __init__(self, slicc, key, value):
+ super(PairAST, self).__init__(slicc)
+ self.key = key
+ self.value = value
+
+ def __repr__(self):
+ return '[%s=%s]' % (self.key, self.value)
diff --git a/src/mem/slicc/ast/PairListAST.py b/src/mem/slicc/ast/PairListAST.py
new file mode 100644
index 000000000..6afe3f4fa
--- /dev/null
+++ b/src/mem/slicc/ast/PairListAST.py
@@ -0,0 +1,37 @@
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.AST import AST
+
+class PairListAST(AST):
+ def __init__(self, slicc):
+ super(PairListAST, self).__init__(slicc)
+
+ def __repr__(self):
+ return "[PairListAST] %r" % self.pairs
+
+ def addPair(self, pair_ast):
+ self[pair_ast.key] = pair_ast.value
diff --git a/src/mem/slicc/ast/PeekStatementAST.cc b/src/mem/slicc/ast/PeekStatementAST.cc
deleted file mode 100644
index 3e92446dd..000000000
--- a/src/mem/slicc/ast/PeekStatementAST.cc
+++ /dev/null
@@ -1,115 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * PeekStatementAST.C
- *
- * Description: See PeekStatementAST.hh
- *
- * $Id$
- *
- */
-
-#include "mem/slicc/ast/PeekStatementAST.hh"
-#include "mem/slicc/symbols/SymbolTable.hh"
-#include "mem/slicc/ast/StatementListAST.hh"
-#include "mem/slicc/ast/TypeAST.hh"
-#include "mem/slicc/ast/VarExprAST.hh"
-
-PeekStatementAST::PeekStatementAST(VarExprAST* queue_name_ptr,
- TypeAST* type_ptr,
- StatementListAST* statementlist_ptr,
- string method)
- : StatementAST()
-{
- m_queue_name_ptr = queue_name_ptr;
- m_type_ptr = type_ptr;
- m_statementlist_ptr = statementlist_ptr;
- m_method = method;
-}
-
-PeekStatementAST::~PeekStatementAST()
-{
- delete m_queue_name_ptr;
- delete m_type_ptr;
- delete m_statementlist_ptr;
-}
-
-void PeekStatementAST::generate(string& code, Type* return_type_ptr) const
-{
- code += indent_str() + "{\n"; // Start scope
- inc_indent();
- g_sym_table.pushFrame();
-
- Type* msg_type_ptr = m_type_ptr->lookupType();
-
- // Add new local var to symbol table
- g_sym_table.newSym(new Var("in_msg", getLocation(), msg_type_ptr, "(*in_msg_ptr)", getPairs()));
-
- // Check the queue type
- m_queue_name_ptr->assertType("InPort");
-
- // Declare the new "in_msg_ptr" variable
- code += indent_str() + "const " + msg_type_ptr->cIdent() + "* in_msg_ptr;\n"; // Declare message
- // code += indent_str() + "in_msg_ptr = static_cast<const ";
- code += indent_str() + "in_msg_ptr = dynamic_cast<const ";
- code += msg_type_ptr->cIdent() + "*>(";
- code += "(" + m_queue_name_ptr->getVar()->getCode() + ")";
- code += ".";
- code += m_method;
- code += "());\n";
-
- code += indent_str() + "assert(in_msg_ptr != NULL);\n"; // Check the cast result
-
- if(CHECK_INVALID_RESOURCE_STALLS) {
- // Declare the "in_buffer_rank" variable
- code += indent_str() + "int in_buffer_rank = "; // Declare message
- code += "(" + m_queue_name_ptr->getVar()->getCode() + ")";
- code += ".getPriority();\n";
- }
-
- m_statementlist_ptr->generate(code, return_type_ptr); // The other statements
- dec_indent();
- g_sym_table.popFrame();
- code += indent_str() + "}\n"; // End scope
-}
-
-void PeekStatementAST::findResources(Map<Var*, string>& resource_list) const
-{
- m_statementlist_ptr->findResources(resource_list);
-}
-
-void PeekStatementAST::print(ostream& out) const
-{
- out << "[PeekStatementAST: " << m_method
- << " queue_name: " << *m_queue_name_ptr
- << " type: " << m_type_ptr->toString()
- << " " << *m_statementlist_ptr
- << "]";
-}
diff --git a/src/mem/slicc/ast/PeekStatementAST.hh b/src/mem/slicc/ast/PeekStatementAST.hh
deleted file mode 100644
index e8c65ce4f..000000000
--- a/src/mem/slicc/ast/PeekStatementAST.hh
+++ /dev/null
@@ -1,91 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * PeekStatementAST.hh
- *
- * Description:
- *
- * $Id$
- *
- */
-
-#ifndef PEEKSTATEMENTAST_H
-#define PEEKSTATEMENTAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/StatementAST.hh"
-
-class StatementListAST;
-class TypeAST;
-class VarExprAST;
-
-class PeekStatementAST : public StatementAST {
-public:
- // Constructors
- PeekStatementAST(VarExprAST* queue_name_ptr,
- TypeAST* type_ptr,
- StatementListAST* statementlist_ptr,
- string method);
- // Destructor
- ~PeekStatementAST();
-
- // Public Methods
- void generate(string& code, Type* return_type_ptr) const;
- void findResources(Map<Var*, string>& resource_list) const;
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- PeekStatementAST(const PeekStatementAST& obj);
- PeekStatementAST& operator=(const PeekStatementAST& obj);
-
- // Data Members (m_ prefix)
- VarExprAST* m_queue_name_ptr;
- TypeAST* m_type_ptr;
- StatementListAST* m_statementlist_ptr;
- string m_method;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const PeekStatementAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const PeekStatementAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //PEEKSTATEMENTAST_H
diff --git a/src/mem/slicc/ast/PeekStatementAST.py b/src/mem/slicc/ast/PeekStatementAST.py
new file mode 100644
index 000000000..5186bf0d5
--- /dev/null
+++ b/src/mem/slicc/ast/PeekStatementAST.py
@@ -0,0 +1,73 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.StatementAST import StatementAST
+from slicc.symbols import Var
+
+class PeekStatementAST(StatementAST):
+ def __init__(self, slicc, queue_name, type_ast, statements, method):
+ super(PeekStatementAST, self).__init__(slicc)
+
+ self.queue_name = queue_name
+ self.type_ast = type_ast
+ self.statements = statements
+ self.method = method
+
+ def __repr__(self):
+ return "[PeekStatementAST: %r queue_name: %r type: %r %r]" % \
+ (self.method, self.queue_name, self.type_ast, self.statements)
+
+ def generate(self, code, return_type):
+ self.symtab.pushFrame()
+
+ msg_type = self.type_ast.type
+
+ # Add new local var to symbol table
+ var = Var(self.symtab, "in_msg", self.location, msg_type, "(*in_msg_ptr)",
+ self.pairs)
+ self.symtab.newSymbol(var)
+
+ # Check the queue type
+ self.queue_name.assertType("InPort")
+
+ # Declare the new "in_msg_ptr" variable
+ mtid = msg_type.ident
+ qcode = self.queue_name.var.code
+ code('''
+{
+ const $mtid* in_msg_ptr;
+ in_msg_ptr = dynamic_cast<const $mtid *>(($qcode).${{self.method}}());
+ assert(in_msg_ptr != NULL);
+''')
+
+ # The other statements
+ self.statements.generate(code, return_type)
+ self.symtab.popFrame()
+ code("}")
+
+ def findResources(self, resources):
+ self.statements.findResources(resources)
diff --git a/src/mem/slicc/ast/ReturnStatementAST.cc b/src/mem/slicc/ast/ReturnStatementAST.cc
deleted file mode 100644
index 8ec937c87..000000000
--- a/src/mem/slicc/ast/ReturnStatementAST.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * ReturnStatementAST.C
- *
- * Description: See ReturnStatementAST.hh
- *
- * $Id$
- *
- */
-
-#include "mem/slicc/ast/ReturnStatementAST.hh"
-
-ReturnStatementAST::ReturnStatementAST(ExprAST* expr_ptr)
- : StatementAST()
-{
- m_expr_ptr = expr_ptr;
-}
-
-ReturnStatementAST::~ReturnStatementAST()
-{
- delete m_expr_ptr;
-}
-
-void ReturnStatementAST::generate(string& code, Type* return_type_ptr) const
-{
- code += indent_str();
- code += "return ";
- Type* actual_type_ptr = m_expr_ptr->generate(code);
- code += ";\n";
-
- // Is return valid here?
- if (return_type_ptr == NULL) {
- error("Invalid 'return' statement");
- }
-
- // The return type must match the return_type_ptr
- if (return_type_ptr != actual_type_ptr) {
- m_expr_ptr->error("Return type miss-match, expected return type is '" + return_type_ptr->toString() +
- "', actual is '" + actual_type_ptr->toString() + "'");
- }
-}
-
-void ReturnStatementAST::findResources(Map<Var*, string>& resource_list) const
-{
- m_expr_ptr->findResources(resource_list);
-}
-
-void ReturnStatementAST::print(ostream& out) const
-{
- out << "[ReturnStatementAST: " << *m_expr_ptr << "]";
-}
diff --git a/src/mem/slicc/ast/ReturnStatementAST.hh b/src/mem/slicc/ast/ReturnStatementAST.hh
deleted file mode 100644
index 1fa1b36d6..000000000
--- a/src/mem/slicc/ast/ReturnStatementAST.hh
+++ /dev/null
@@ -1,83 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * ReturnStatementAST.hh
- *
- * Description:
- *
- * $Id$
- *
- */
-
-#ifndef ReturnStatementAST_H
-#define ReturnStatementAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/StatementAST.hh"
-#include "mem/slicc/ast/ExprAST.hh"
-
-class ReturnStatementAST : public StatementAST {
-public:
- // Constructors
- ReturnStatementAST(ExprAST* expr_ptr);
-
- // Destructor
- ~ReturnStatementAST();
-
- // Public Methods
- void generate(string& code, Type* return_type_ptr) const;
- void findResources(Map<Var*, string>& resource_list) const;
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- ReturnStatementAST(const ReturnStatementAST& obj);
- ReturnStatementAST& operator=(const ReturnStatementAST& obj);
-
- // Data Members (m_ prefix)
- ExprAST* m_expr_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const ReturnStatementAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const ReturnStatementAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //ReturnStatementAST_H
diff --git a/src/mem/slicc/ast/ReturnStatementAST.py b/src/mem/slicc/ast/ReturnStatementAST.py
new file mode 100644
index 000000000..f1aff1c32
--- /dev/null
+++ b/src/mem/slicc/ast/ReturnStatementAST.py
@@ -0,0 +1,54 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.StatementAST import StatementAST
+
+class ReturnStatementAST(StatementAST):
+ def __init__(self, slicc, expr_ast):
+ super(ReturnStatementAST, self).__init__(slicc)
+
+ self.expr_ast = expr_ast
+
+ def __repr__(self):
+ return "[ReturnStatementAST: %r]" % self.expr_ast
+
+ def generate(self, code, return_type):
+ actual_type, ecode = self.expr_ast.inline(True)
+ code('return $ecode;')
+
+ # Is return valid here?
+ if return_type is None:
+ self.error("Invalid 'return' statement")
+
+ # The return type must match
+ if return_type != actual_type:
+ self.expr_ast.error("Return type miss-match, expected return " +
+ "type is '%s', actual is '%s'",
+ return_type, actual_type)
+
+ def findResources(self, resources):
+ self.expr_ast.findResources(resources)
diff --git a/src/mem/slicc/ast/StatementAST.hh b/src/mem/slicc/ast/StatementAST.hh
deleted file mode 100644
index 9946541d3..000000000
--- a/src/mem/slicc/ast/StatementAST.hh
+++ /dev/null
@@ -1,88 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * StatementAST.hh
- *
- * Description:
- *
- * $Id$
- *
- */
-
-#ifndef STATEMENTAST_H
-#define STATEMENTAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/AST.hh"
-
-void inc_indent();
-void dec_indent();
-string indent_str();
-
-class StatementAST : public AST {
-public:
- // Constructors
- StatementAST() : AST() {}
- StatementAST(Map<string, string> pairs) : AST(pairs) {}
-
- // Destructor
- //~StatementAST();
-
- // Public Methods
- virtual void generate(string& code, Type* return_type_ptr) const = 0;
- virtual void findResources(Map<Var*, string>& resource_list) const { }
-
- //void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- //StatementAST(const StatementAST& obj);
- //StatementAST& operator=(const StatementAST& obj);
-
- // Data Members (m_ prefix)
-
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const StatementAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const StatementAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //STATEMENTAST_H
diff --git a/src/mem/slicc/ast/StatementAST.py b/src/mem/slicc/ast/StatementAST.py
new file mode 100644
index 000000000..017b2b1ed
--- /dev/null
+++ b/src/mem/slicc/ast/StatementAST.py
@@ -0,0 +1,34 @@
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.AST import AST
+
+class StatementAST(AST):
+ def __init__(self, slicc, pairs=None):
+ super(StatementAST, self).__init__(slicc, pairs)
+
+ def findResources(self, resources):
+ pass
diff --git a/src/mem/slicc/ast/StatementListAST.cc b/src/mem/slicc/ast/StatementListAST.cc
deleted file mode 100644
index 0f5817f7c..000000000
--- a/src/mem/slicc/ast/StatementListAST.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * StatementListAST.C
- *
- * Description: See StatementListAST.hh
- *
- * $Id$
- *
- */
-
-#include "mem/slicc/ast/StatementListAST.hh"
-
-StatementListAST::StatementListAST(Vector<StatementAST*>* vec_ptr)
- : AST()
-{
- assert(vec_ptr != NULL);
- m_vec_ptr = vec_ptr;
-}
-
-// Singleton constructor.
-StatementListAST::StatementListAST(StatementAST* statement_ptr)
- : AST()
-{
- assert(statement_ptr != NULL);
- m_vec_ptr = new Vector<StatementAST*>;
- m_vec_ptr->insertAtTop(statement_ptr);
-}
-
-StatementListAST::~StatementListAST()
-{
- int size = m_vec_ptr->size();
- for(int i=0; i<size; i++) {
- delete (*m_vec_ptr)[i];
- }
- delete m_vec_ptr;
-}
-
-void StatementListAST::generate(string& code, Type* return_type_ptr) const
-{
- int size = m_vec_ptr->size();
- for(int i=0; i<size; i++) {
- (*m_vec_ptr)[i]->generate(code, return_type_ptr);
- }
-}
-
-void StatementListAST::findResources(Map<Var*, string>& resource_list) const
-{
- int size = m_vec_ptr->size();
- for(int i=0; i<size; i++) {
- (*m_vec_ptr)[i]->findResources(resource_list);
- }
-}
-
-void StatementListAST::print(ostream& out) const
-{
- assert(m_vec_ptr != NULL);
- out << "[StatementListAST: " << *m_vec_ptr << "]";
-}
diff --git a/src/mem/slicc/ast/StatementListAST.hh b/src/mem/slicc/ast/StatementListAST.hh
deleted file mode 100644
index 831e2481a..000000000
--- a/src/mem/slicc/ast/StatementListAST.hh
+++ /dev/null
@@ -1,85 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * StatementListAST.hh
- *
- * Description:
- *
- * $Id$
- *
- */
-
-#ifndef STATEMENTLISTAST_H
-#define STATEMENTLISTAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/AST.hh"
-#include "mem/slicc/ast/StatementAST.hh"
-class Var;
-
-class StatementListAST : public AST {
-public:
- // Constructors
- StatementListAST(Vector<StatementAST*>* vec_ptr);
- StatementListAST(StatementAST* statement_ptr);
-
- // Destructor
- ~StatementListAST();
-
- // Public Methods
- void generate(string& code, Type* return_type_ptr) const;
- void findResources(Map<Var*, string>& resource_list) const;
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- StatementListAST(const StatementListAST& obj);
- StatementListAST& operator=(const StatementListAST& obj);
-
- // Data Members (m_ prefix)
- Vector<StatementAST*>* m_vec_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const StatementListAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const StatementListAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //STATEMENTLISTAST_H
diff --git a/src/mem/slicc/ast/StatementListAST.py b/src/mem/slicc/ast/StatementListAST.py
new file mode 100644
index 000000000..1475c5c97
--- /dev/null
+++ b/src/mem/slicc/ast/StatementListAST.py
@@ -0,0 +1,46 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.AST import AST
+
+class StatementListAST(AST):
+ def __init__(self, slicc, statements):
+ super(StatementListAST, self).__init__(slicc)
+ if not isinstance(statements, (list, tuple)):
+ statements = [ statements ]
+ self.statements = statements
+
+ def __repr__(self):
+ return "[StatementListAST: %r]" % self.statements
+
+ def generate(self, code, return_type):
+ for statement in self.statements:
+ statement.generate(code, return_type)
+
+ def findResources(self, resources):
+ for statement in self.statements:
+ statement.findResources(resources)
diff --git a/src/mem/slicc/ast/TransitionDeclAST.cc b/src/mem/slicc/ast/TransitionDeclAST.cc
deleted file mode 100644
index 66b7ca132..000000000
--- a/src/mem/slicc/ast/TransitionDeclAST.cc
+++ /dev/null
@@ -1,89 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * TransitionDeclAST.C
- *
- * Description: See TransitionDeclAST.hh
- *
- * $Id$
- *
- */
-
-#include "mem/slicc/ast/TransitionDeclAST.hh"
-#include "mem/slicc/symbols/Transition.hh"
-
-TransitionDeclAST::TransitionDeclAST(Vector<string>* state_list_ptr,
- Vector<string>* event_list_ptr,
- string* next_state_ptr,
- PairListAST* pairs_ptr,
- Vector<string>* action_list_ptr)
- : DeclAST(pairs_ptr)
-{
- m_state_list_ptr = state_list_ptr;
- m_event_list_ptr = event_list_ptr;
- m_next_state_ptr = next_state_ptr;
- m_action_list_ptr = action_list_ptr;
-}
-
-TransitionDeclAST::~TransitionDeclAST()
-{
- delete m_state_list_ptr;
- delete m_event_list_ptr;
- delete m_next_state_ptr;
- delete m_action_list_ptr;
-}
-
-void TransitionDeclAST::generate()
-{
- Vector<string>& states = *m_state_list_ptr;
- Vector<string>& events = *m_event_list_ptr;
-
- StateMachine* machine_ptr = g_sym_table.getStateMachine();
- if (machine_ptr == NULL) {
- error("Transition declaration not part of a machine.");
- } else if (m_next_state_ptr == NULL) {
- for (int i=0; i<states.size(); i++) {
- for (int j=0; j<events.size(); j++) {
- machine_ptr->addTransition(new Transition(states[i], events[j], states[i], *m_action_list_ptr, getLocation(), getPairs()));
- }
- }
- } else {
- for (int i=0; i<states.size(); i++) {
- for (int j=0; j<events.size(); j++) {
- machine_ptr->addTransition(new Transition(states[i], events[j], *m_next_state_ptr, *m_action_list_ptr, getLocation(), getPairs()));
- }
- }
- }
-}
-
-void TransitionDeclAST::print(ostream& out) const
-{
- out << "[TransitionDecl: ]";
-}
diff --git a/src/mem/slicc/ast/TransitionDeclAST.hh b/src/mem/slicc/ast/TransitionDeclAST.hh
deleted file mode 100644
index f07f0a3c2..000000000
--- a/src/mem/slicc/ast/TransitionDeclAST.hh
+++ /dev/null
@@ -1,89 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * TransistionDeclAST.hh
- *
- * Description:
- *
- * $Id: TransitionDeclAST.hh,v 3.2 2003/07/10 18:08:07 milo Exp $
- *
- */
-
-#ifndef TransitionDeclAST_H
-#define TransitionDeclAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/DeclAST.hh"
-#include "mem/slicc/ast/StatementListAST.hh"
-
-class TransitionDeclAST : public DeclAST {
-public:
- // Constructors
- TransitionDeclAST(Vector<string>* state_list_ptr,
- Vector<string>* event_list_ptr,
- string* next_state_ptr,
- PairListAST* pairs_ptr,
- Vector<string>* action_list_ptr);
-
- // Destructor
- ~TransitionDeclAST();
-
- // Public Methods
- void generate();
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- TransitionDeclAST(const TransitionDeclAST& obj);
- TransitionDeclAST& operator=(const TransitionDeclAST& obj);
-
- // Data Members (m_ prefix)
- Vector<string>* m_state_list_ptr;
- Vector<string>* m_event_list_ptr;
- string* m_next_state_ptr;
- Vector<string>* m_action_list_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const TransitionDeclAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const TransitionDeclAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //TransitionDeclAST_H
diff --git a/src/mem/slicc/ast/TransitionDeclAST.py b/src/mem/slicc/ast/TransitionDeclAST.py
new file mode 100644
index 000000000..a941d7b0c
--- /dev/null
+++ b/src/mem/slicc/ast/TransitionDeclAST.py
@@ -0,0 +1,65 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.DeclAST import DeclAST
+from slicc.symbols import Transition
+
+class TransitionDeclAST(DeclAST):
+ def __init__(self, slicc, states, events, next_state, pairs, actions):
+ super(TransitionDeclAST, self).__init__(slicc, pairs)
+
+ self.states = states
+ self.events = events
+ self.next_state = next_state
+ self.actions = actions
+
+ def __repr__(self):
+ return "[TransitionDecl: ]"
+
+ def generate(self):
+ machine = self.symtab.state_machine
+
+ if machine is None:
+ self.error("Transition declaration not part of a machine.")
+
+ for action in self.actions:
+ if action not in machine.actions:
+ self.error("Invalid action: %s is not part of machine: %s" % \
+ (action, machine))
+
+ for state in self.states:
+ if state not in machine.states:
+ self.error("Invalid state: %s is not part of machine: %s" % \
+ (state, machine))
+ next_state = self.next_state or state
+ for event in self.events:
+ if event not in machine.events:
+ self.error("Invalid event: %s is not part of machine: %s" % \
+ (event, machine))
+ t = Transition(self.symtab, machine, state, event, next_state,
+ self.actions, self.location, self.pairs)
+ machine.addTransition(t)
diff --git a/src/mem/slicc/ast/TypeAST.py b/src/mem/slicc/ast/TypeAST.py
new file mode 100644
index 000000000..209859b8d
--- /dev/null
+++ b/src/mem/slicc/ast/TypeAST.py
@@ -0,0 +1,53 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.AST import AST
+
+from slicc.symbols import Type
+
+class TypeAST(AST):
+ def __init__(self, slicc, ident):
+ super(TypeAST, self).__init__(slicc)
+
+ self.ident = ident
+
+ def __repr__(self):
+ return self.ident
+
+ def __str__(self):
+ return self.ident
+
+ @property
+ def type(self, assert_type=None):
+ type = self.symtab.find(self.ident, Type)
+ if not type:
+ self.error("Type '%s' not declared.", self)
+
+ if assert_type is not None and type != assert_type:
+ self.error("Type '%s' is should be type '%s'", self, assert_type)
+
+ return type
diff --git a/src/mem/slicc/ast/TypeDeclAST.hh b/src/mem/slicc/ast/TypeDeclAST.hh
deleted file mode 100644
index 8a72c0406..000000000
--- a/src/mem/slicc/ast/TypeDeclAST.hh
+++ /dev/null
@@ -1,86 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * TypeDeclAST.hh
- *
- * Description:
- *
- * $Id: TypeDeclAST.hh,v 3.2 2003/03/17 01:55:28 xu Exp $
- *
- */
-
-#ifndef TypeDeclAST_H
-#define TypeDeclAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/DeclAST.hh"
-#include "mem/slicc/ast/TypeAST.hh"
-#include "mem/slicc/ast/TypeFieldAST.hh"
-
-class TypeDeclAST : public DeclAST {
-public:
- // Constructors
- TypeDeclAST(TypeAST* type_ast_ptr,
- PairListAST* pairs_ptr,
- Vector<TypeFieldAST*>* field_vec_ptr);
-
- // Destructor
- ~TypeDeclAST();
-
- // Public Methods
- virtual void generate();
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- TypeDeclAST(const TypeDeclAST& obj);
- TypeDeclAST& operator=(const TypeDeclAST& obj);
-
- // Data Members (m_ prefix)
- TypeAST* m_type_ast_ptr;
- Vector<TypeFieldAST*>* m_field_vec_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const TypeDeclAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const TypeDeclAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //TypeDeclAST_H
diff --git a/src/mem/slicc/ast/TypeDeclAST.py b/src/mem/slicc/ast/TypeDeclAST.py
new file mode 100644
index 000000000..ecdb5949b
--- /dev/null
+++ b/src/mem/slicc/ast/TypeDeclAST.py
@@ -0,0 +1,61 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.DeclAST import DeclAST
+from slicc.symbols.Type import Type
+
+class TypeDeclAST(DeclAST):
+ def __init__(self, slicc, type_ast, pairs, field_asts):
+ super(TypeDeclAST, self).__init__(slicc, pairs)
+
+ self.type_ast = type_ast
+ self.field_asts = field_asts
+
+ def __repr__(self):
+ return "[TypeDecl: %r]" % (self.type_ast)
+
+ def files(self, parent=None):
+ if "external" in self:
+ return set()
+
+ if parent:
+ ident = "%s_%s" % (parent, self.type_ast.ident)
+ else:
+ ident = self.type_ast.ident
+ return set(("%s.hh" % ident, "%s.cc" % ident))
+
+ def generate(self):
+ ident = str(self.type_ast)
+
+ # Make the new type
+ new_type = Type(self.symtab, ident, self.location, self.pairs,
+ self.state_machine)
+ self.symtab.newSymbol(new_type)
+
+ # Add all of the fields of the type to it
+ for field in self.field_asts:
+ field.generate(new_type)
diff --git a/src/mem/slicc/ast/TypeFieldAST.hh b/src/mem/slicc/ast/TypeFieldAST.hh
deleted file mode 100644
index 144372047..000000000
--- a/src/mem/slicc/ast/TypeFieldAST.hh
+++ /dev/null
@@ -1,83 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * TypeFieldAST.hh
- *
- * Description:
- *
- * $Id$
- *
- */
-
-#ifndef TypeFieldAST_H
-#define TypeFieldAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/symbols/StateMachine.hh"
-#include "mem/slicc/ast/StatementListAST.hh"
-#include "mem/slicc/ast/PairListAST.hh"
-#include "mem/slicc/ast/ExprAST.hh"
-
-class TypeFieldAST : public AST {
-public:
- // Constructors
- TypeFieldAST(PairListAST* pairs_ptr);
-
- // Destructor
- virtual ~TypeFieldAST() {}
-
- // Public Methods
- virtual void generate(Type *type_ptr) = 0;
- virtual void print(ostream& out) const = 0;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- // TypeFieldAST(const TypeFieldAST& obj);
- // TypeFieldAST& operator=(const TypeFieldAST& obj);
-
- // Data Members (m_ prefix)
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const TypeFieldAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const TypeFieldAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //TypeFieldAST_H
diff --git a/src/mem/slicc/ast/TypeFieldAST.py b/src/mem/slicc/ast/TypeFieldAST.py
new file mode 100644
index 000000000..7dd4c74aa
--- /dev/null
+++ b/src/mem/slicc/ast/TypeFieldAST.py
@@ -0,0 +1,32 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.AST import AST
+
+class TypeFieldAST(AST):
+ def __init__(self, slicc, pairs):
+ super(TypeFieldAST, self).__init__(slicc, pairs)
diff --git a/src/mem/slicc/ast/TypeFieldEnumAST.cc b/src/mem/slicc/ast/TypeFieldEnumAST.cc
deleted file mode 100644
index 1a02f7edd..000000000
--- a/src/mem/slicc/ast/TypeFieldEnumAST.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * TypeFieldEnumAST.C
- *
- * Description: See TypeFieldEnumAST.hh
- *
- * $Id$
- *
- */
-
-#include "mem/slicc/ast/TypeFieldEnumAST.hh"
-#include "mem/slicc/symbols/State.hh"
-#include "mem/slicc/symbols/Event.hh"
-
-TypeFieldEnumAST::TypeFieldEnumAST(string* field_id_ptr,
- PairListAST* pairs_ptr)
- : TypeFieldAST(pairs_ptr)
-{
- m_field_id_ptr = field_id_ptr;
- m_pairs_ptr = pairs_ptr;
-}
-
-TypeFieldEnumAST::~TypeFieldEnumAST()
-{
- delete m_field_id_ptr;
-}
-
-void TypeFieldEnumAST::generate(Type *type_ptr)
-{
- // Add enumeration
- if (!type_ptr->enumAdd(*m_field_id_ptr, m_pairs_ptr->getPairs())) {
- error("Duplicate enumeration: " + type_ptr->toString() + ":" + *m_field_id_ptr);
- }
-
- // Fill machine info
- StateMachine* machine_ptr = g_sym_table.getStateMachine();
- if (type_ptr->toString() == "State") {
- if (machine_ptr == NULL) {
- error("State declaration not part of a machine.");
- }
- machine_ptr->addState(new State(*m_field_id_ptr, getLocation(), getPairs()));
- }
- if (type_ptr->toString() == "Event") {
- if (machine_ptr == NULL) {
- error("Event declaration not part of a machine.");
- }
- machine_ptr->addEvent(new Event(*m_field_id_ptr, getLocation(), getPairs()));
- }
-}
-
-void TypeFieldEnumAST::print(ostream& out) const
-{
- out << "[TypeFieldEnum: " << *m_field_id_ptr << "]";
-}
diff --git a/src/mem/slicc/ast/TypeFieldEnumAST.hh b/src/mem/slicc/ast/TypeFieldEnumAST.hh
deleted file mode 100644
index cd02f03bb..000000000
--- a/src/mem/slicc/ast/TypeFieldEnumAST.hh
+++ /dev/null
@@ -1,86 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * TypeFieldEnumAST.hh
- *
- * Description:
- *
- * $Id: TypeFieldEnumAST.hh,v 3.2 2003/07/10 18:08:07 milo Exp $
- *
- */
-
-#ifndef TypeFieldEnumAST_H
-#define TypeFieldEnumAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/symbols/StateMachine.hh"
-#include "mem/slicc/ast/TypeFieldAST.hh"
-#include "mem/slicc/ast/StatementListAST.hh"
-#include "mem/slicc/ast/PairListAST.hh"
-
-class TypeFieldEnumAST : public TypeFieldAST {
-public:
- // Constructors
- TypeFieldEnumAST(string* field_id_ptr,
- PairListAST* pairs_ptr);
-
- // Destructor
- ~TypeFieldEnumAST();
-
- // Public Methods
- void generate(Type *type_ptr);
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- TypeFieldEnumAST(const TypeFieldEnumAST& obj);
- TypeFieldEnumAST& operator=(const TypeFieldEnumAST& obj);
-
- // Data Members (m_ prefix)
- string* m_field_id_ptr;
- PairListAST* m_pairs_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const TypeFieldEnumAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const TypeFieldEnumAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //TypeFieldEnumAST_H
diff --git a/src/mem/slicc/ast/TypeFieldEnumAST.py b/src/mem/slicc/ast/TypeFieldEnumAST.py
new file mode 100644
index 000000000..138fff793
--- /dev/null
+++ b/src/mem/slicc/ast/TypeFieldEnumAST.py
@@ -0,0 +1,59 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.TypeFieldAST import TypeFieldAST
+from slicc.symbols import Event, State
+
+class TypeFieldEnumAST(TypeFieldAST):
+ def __init__(self, slicc, field_id, pairs_ast):
+ super(TypeFieldEnumAST, self).__init__(slicc, pairs_ast)
+
+ self.field_id = field_id
+ self.pairs_ast = pairs_ast
+
+ def __repr__(self):
+ return "[TypeFieldEnum: %r]" % self.field_id
+
+ def generate(self, type):
+ # Add enumeration
+ if not type.enumAdd(self.field_id, self.pairs_ast.pairs):
+ self.error("Duplicate enumeration: %s:%s" % (type, self.field_id))
+
+ # Fill machine info
+ machine = self.symtab.state_machine
+
+ if str(type) == "State":
+ if not machine:
+ self.error("State declaration not part of a machine.")
+ s = State(self.symtab, self.field_id, self.location, self.pairs)
+ machine.addState(s)
+
+ if str(type) == "Event":
+ if not machine:
+ self.error("Event declaration not part of a machine.")
+ e = Event(self.symtab, self.field_id, self.location, self.pairs)
+ machine.addEvent(e)
diff --git a/src/mem/slicc/ast/TypeFieldMemberAST.cc b/src/mem/slicc/ast/TypeFieldMemberAST.cc
deleted file mode 100644
index 1fe0f6d4b..000000000
--- a/src/mem/slicc/ast/TypeFieldMemberAST.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * TypeFieldMemberAST.C
- *
- * Description: See TypeFieldMemberAST.hh
- *
- * $Id: TypeFieldMemberAST.C,v 3.1 2003/03/27 22:58:54 xu Exp $
- *
- */
-
-#include "mem/slicc/ast/TypeFieldMemberAST.hh"
-
-TypeFieldMemberAST::TypeFieldMemberAST(TypeAST* type_ast_ptr,
- string* field_id_ptr,
- PairListAST* pairs_ptr,
- ExprAST* rvalue_ptr)
- : TypeFieldAST(pairs_ptr)
-{
- m_type_ast_ptr = type_ast_ptr;
- m_field_id_ptr = field_id_ptr;
- m_rvalue_ptr = rvalue_ptr;
-}
-
-TypeFieldMemberAST::~TypeFieldMemberAST()
-{
- delete m_type_ast_ptr;
- delete m_field_id_ptr;
- if(m_rvalue_ptr) delete m_rvalue_ptr;
-}
-
-void TypeFieldMemberAST::generate(Type *type_ptr)
-{
- // Lookup type
- Type* field_type_ptr = m_type_ast_ptr->lookupType();
-
- // check type if this is a initialization
- string* init_code = NULL;
- if(m_rvalue_ptr) {
- init_code = new string();
- Type* rvalue_type_ptr = m_rvalue_ptr->generate(*init_code);
- if(field_type_ptr != rvalue_type_ptr) {
- error("Initialization type mismatch '" + field_type_ptr->toString() + "' and '" + rvalue_type_ptr->toString() + "'");
- }
- }
-
- // Add data member to the parent type
- if (!type_ptr->dataMemberAdd(*m_field_id_ptr, field_type_ptr, getPairs(),
- init_code)) {
- error("Duplicate data member: " + type_ptr->toString() + ":" + *m_field_id_ptr);
- }
-}
-
-void TypeFieldMemberAST::print(ostream& out) const
-{
- out << "[TypeFieldMember: " << *m_field_id_ptr << "]";
-}
diff --git a/src/mem/slicc/ast/TypeFieldMemberAST.hh b/src/mem/slicc/ast/TypeFieldMemberAST.hh
deleted file mode 100644
index 47355f3ac..000000000
--- a/src/mem/slicc/ast/TypeFieldMemberAST.hh
+++ /dev/null
@@ -1,91 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * TypeFieldMemberAST.hh
- *
- * Description:
- *
- * $Id$
- *
- */
-
-#ifndef TypeFieldMemberAST_H
-#define TypeFieldMemberAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/TypeFieldAST.hh"
-#include "mem/slicc/symbols/StateMachine.hh"
-#include "mem/slicc/ast/StatementListAST.hh"
-#include "mem/slicc/ast/PairListAST.hh"
-#include "mem/slicc/ast/ExprAST.hh"
-#include "mem/slicc/ast/TypeAST.hh"
-
-class TypeFieldMemberAST : public TypeFieldAST {
-public:
- // Constructors
- TypeFieldMemberAST(TypeAST* type_ast_ptr,
- string* field_id_ptr,
- PairListAST* pairs_ptr,
- ExprAST* rvalue_ptr);
-
- // Destructor
- ~TypeFieldMemberAST();
-
- // Public Methods
- void generate(Type *type_ptr);
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- TypeFieldMemberAST(const TypeFieldMemberAST& obj);
- TypeFieldMemberAST& operator=(const TypeFieldMemberAST& obj);
-
- // Data Members (m_ prefix)
- TypeAST* m_type_ast_ptr;
- string* m_field_id_ptr;
- ExprAST* m_rvalue_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const TypeFieldMemberAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const TypeFieldMemberAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //TypeFieldMemberAST_H
diff --git a/src/mem/slicc/ast/TypeFieldMemberAST.py b/src/mem/slicc/ast/TypeFieldMemberAST.py
new file mode 100644
index 000000000..a60153664
--- /dev/null
+++ b/src/mem/slicc/ast/TypeFieldMemberAST.py
@@ -0,0 +1,57 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.TypeFieldAST import TypeFieldAST
+
+class TypeFieldMemberAST(TypeFieldAST):
+ def __init__(self, slicc, type_ast, field_id, pairs, rvalue):
+ super(TypeFieldMemberAST, self).__init__(slicc, pairs)
+
+ self.type_ast = type_ast
+ self.field_id = field_id
+ self.rvalue = rvalue
+
+ def __repr__(self):
+ return "[TypeFieldMember: %r]" % self.field_id
+
+ def generate(self, type):
+ # Lookup type
+ field_type = self.type_ast.type
+
+ # check type if this is a initialization
+ init_code = ""
+ if self.rvalue:
+ rvalue_type,init_code = self.rvalue.inline(True)
+ if field_type != rvalue_type:
+ self.error("Initialization type mismatch '%s' and '%s'" % \
+ (field_type, rvalue_type))
+
+ # Add data member to the parent type
+ if not type.dataMemberAdd(self.field_id, field_type, self.pairs,
+ init_code):
+
+ self.error("Duplicate data member: %s:%s" % (type_ptr, field_id))
diff --git a/src/mem/slicc/ast/TypeFieldMethodAST.cc b/src/mem/slicc/ast/TypeFieldMethodAST.cc
deleted file mode 100644
index 03c528f87..000000000
--- a/src/mem/slicc/ast/TypeFieldMethodAST.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * TypeFieldMethodAST.C
- *
- * Description: See TypeFieldMethodAST.hh
- *
- * $Id: TypeFieldMethodAST.C,v 3.1 2003/07/10 18:08:07 milo Exp $
- *
- */
-
-#include "mem/slicc/ast/TypeFieldMethodAST.hh"
-
-TypeFieldMethodAST::TypeFieldMethodAST(TypeAST* return_type_ast_ptr,
- string* ident_ptr,
- Vector<TypeAST*>* type_ast_vec_ptr,
- PairListAST* pairs_ptr)
- : TypeFieldAST(pairs_ptr)
-{
- m_return_type_ast_ptr = return_type_ast_ptr;
- m_ident_ptr = ident_ptr;
- m_type_ast_vec_ptr = type_ast_vec_ptr;
-}
-
-TypeFieldMethodAST::~TypeFieldMethodAST()
-{
- delete m_return_type_ast_ptr;
- delete m_ident_ptr;
-
- int size = m_type_ast_vec_ptr->size();
- for(int i=0; i<size; i++) {
- delete (*m_type_ast_vec_ptr)[i];
- }
- delete m_type_ast_vec_ptr;
-}
-
-void TypeFieldMethodAST::generate(Type *type_ptr)
-{
- // Lookup return type
- Type* return_type_ptr = m_return_type_ast_ptr->lookupType();
-
- // Lookup parameter types
- Vector<Type*> type_vec;
- int size = m_type_ast_vec_ptr->size();
- for(int i=0; i<size; i++) {
- Type* type_ptr = (*m_type_ast_vec_ptr)[i]->lookupType();
- type_vec.insertAtBottom(type_ptr);
- }
-
- // Add method
- if (!type_ptr->methodAdd(*m_ident_ptr, return_type_ptr, type_vec)) { // Return false on error
- error("Duplicate method: " + type_ptr->toString() + ":" + *m_ident_ptr + "()");
- }
-}
diff --git a/src/mem/slicc/ast/TypeFieldMethodAST.hh b/src/mem/slicc/ast/TypeFieldMethodAST.hh
deleted file mode 100644
index 10d53ef80..000000000
--- a/src/mem/slicc/ast/TypeFieldMethodAST.hh
+++ /dev/null
@@ -1,87 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * TypeFieldMethodAST.hh
- *
- * Description:
- *
- * $Id: TypeFieldMethodAST.hh,v 3.2 2003/07/10 18:08:07 milo Exp $
- *
- */
-
-#ifndef TYPEFIELDMETHODAST_H
-#define TYPEFIELDMETHODAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/TypeFieldAST.hh"
-#include "mem/slicc/ast/TypeAST.hh"
-
-class TypeFieldMethodAST : public TypeFieldAST {
-public:
- // Constructors
- TypeFieldMethodAST(TypeAST* return_type_ast_ptr,
- string* ident_ptr,
- Vector<TypeAST*>* type_ast_vec_ptr,
- PairListAST* pairs_ptr);
- // Destructor
- ~TypeFieldMethodAST();
-
- // Public Methods
-
- void generate(Type *type_ptr);
- void print(ostream& out) const {}
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- TypeFieldMethodAST(const TypeFieldMethodAST& obj);
- TypeFieldMethodAST& operator=(const TypeFieldMethodAST& obj);
-
- // Data Members (m_ prefix)
- TypeAST* m_return_type_ast_ptr;
- string* m_ident_ptr;
- Vector<TypeAST*>* m_type_ast_vec_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const TypeFieldMethodAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const TypeFieldMethodAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //TYPEFIELDMETHODAST_H
diff --git a/src/mem/slicc/ast/TypeFieldMethodAST.py b/src/mem/slicc/ast/TypeFieldMethodAST.py
new file mode 100644
index 000000000..2c8cf3f7b
--- /dev/null
+++ b/src/mem/slicc/ast/TypeFieldMethodAST.py
@@ -0,0 +1,50 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.TypeFieldAST import TypeFieldAST
+
+class TypeFieldMethodAST(TypeFieldAST):
+ def __init__(self, slicc, return_type_ast, ident, type_asts, pairs):
+ super(TypeFieldMethodAST, self).__init__(slicc, pairs)
+
+ self.return_type_ast = return_type_ast
+ self.ident = ident
+ self.type_asts = type_asts
+
+ def __repr__(self):
+ return ""
+
+ def generate(self, type):
+ # Lookup return type
+ return_type = self.return_type_ast.type
+
+ # Lookup parameter types
+ types = [ t.type for t in self.type_asts ]
+
+ # Add method
+ if not type.methodAdd(self.ident, return_type, types):
+ self.error("Duplicate method: %s:%s()" % (type, self.ident))
diff --git a/src/mem/slicc/ast/VarExprAST.cc b/src/mem/slicc/ast/VarExprAST.cc
deleted file mode 100644
index 13e265540..000000000
--- a/src/mem/slicc/ast/VarExprAST.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * VarExprAST.C
- *
- * Description: See VarExprAST.hh
- *
- * $Id$
- *
- */
-
-#include "mem/slicc/ast/VarExprAST.hh"
-#include "mem/slicc/ast/StatementAST.hh"
-#include "mem/slicc/symbols/SymbolTable.hh"
-
-VarExprAST::~VarExprAST()
-{
- delete m_var_ptr;
-}
-
-
-Var* VarExprAST::getVar() const
-{
- string var = *m_var_ptr;
- Var* var_ptr = g_sym_table.getVar(var);
- if (var_ptr == NULL) {
- error("Unrecognized variable: " + var);
- }
- return var_ptr;
-}
-
-void VarExprAST::assertType(string type_ident) const
-{
- Type* expected_type_ptr = g_sym_table.getType(type_ident);
- if (expected_type_ptr == NULL) {
- error("There must be a type '" + type_ident + "' declared in this scope");
- }
-
- if (getVar()->getType() != expected_type_ptr) {
- error("Incorrect type: '" + getVar()->getIdent() + "' is expected to be type '" + expected_type_ptr->toString() + "'");
- }
-}
-
-Type* VarExprAST::generate(string& code) const
-{
- Var* var_ptr = getVar();
- code += var_ptr->getCode();
- return var_ptr->getType();
-}
diff --git a/src/mem/slicc/ast/VarExprAST.hh b/src/mem/slicc/ast/VarExprAST.hh
deleted file mode 100644
index ea32582a2..000000000
--- a/src/mem/slicc/ast/VarExprAST.hh
+++ /dev/null
@@ -1,86 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * VarExprAST.hh
- *
- * Description:
- *
- * $Id$
- *
- */
-
-#ifndef VAREXPRAST_H
-#define VAREXPRAST_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/ExprAST.hh"
-class Var;
-
-class VarExprAST : public ExprAST {
-public:
- // Constructors
- VarExprAST(string* var_ptr) : ExprAST() { m_var_ptr = var_ptr; }
-
- // Destructor
- ~VarExprAST();
-
- // Public Methods
- Type* generate(string& code) const;
- void print(ostream& out) const { out << "[VarExprAST: " << *m_var_ptr << "]"; }
- string getName() const { return *m_var_ptr; }
- Var* getVar() const;
- void assertType(string type_ident) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- VarExprAST(const VarExprAST& obj);
- VarExprAST& operator=(const VarExprAST& obj);
-
- // Data Members (m_ prefix)
- string* m_var_ptr;
-
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const VarExprAST& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const VarExprAST& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //VAREXPRAST_H
diff --git a/src/mem/slicc/ast/VarExprAST.py b/src/mem/slicc/ast/VarExprAST.py
new file mode 100644
index 000000000..ac440bb68
--- /dev/null
+++ b/src/mem/slicc/ast/VarExprAST.py
@@ -0,0 +1,66 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.ExprAST import ExprAST
+from slicc.symbols import Type, Var
+
+class VarExprAST(ExprAST):
+ def __init__(self, slicc, var):
+ super(VarExprAST, self).__init__(slicc)
+ self._var = var
+
+ def __repr__(self):
+ return "[VarExprAST: %r]" % self._var
+
+ @property
+ def name(self):
+ return str(self._var)
+
+ @property
+ def var(self):
+ var = self.symtab.find(self._var, Var)
+ if not var:
+ self.error("Unrecognized variable: %s", self._var)
+ return var
+
+ def assertType(self, type_ident):
+ expected_type = self.symtab.find(type_ident, Type)
+
+ if not expected_type:
+ self.error("There must be a type '%s' declared in this scope",
+ type_ident)
+
+ if self.var.type != expected_type:
+ self.error("Incorrect type: " + \
+ "'%s' is expected to be type '%s' not '%s'",
+ self.var.ident, expected_type, self.var.type)
+
+ def generate(self, code):
+ fix = code.nofix()
+ code("${{self.var.code}}")
+ code.fix(fix)
+ return self.var.type
diff --git a/src/mem/slicc/ast/__init__.py b/src/mem/slicc/ast/__init__.py
new file mode 100644
index 000000000..de50cbd49
--- /dev/null
+++ b/src/mem/slicc/ast/__init__.py
@@ -0,0 +1,69 @@
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.ast.AST import *
+
+# actual ASTs
+from slicc.ast.ActionDeclAST import *
+from slicc.ast.AssignStatementAST import *
+from slicc.ast.CheckAllocateStatementAST import *
+from slicc.ast.CheckStopSlotsStatementAST import *
+from slicc.ast.ChipComponentAccessAST import *
+from slicc.ast.CopyHeadStatementAST import *
+from slicc.ast.DeclAST import *
+from slicc.ast.DeclListAST import *
+from slicc.ast.EnqueueStatementAST import *
+from slicc.ast.EnumDeclAST import *
+from slicc.ast.EnumExprAST import *
+from slicc.ast.ExprAST import *
+from slicc.ast.ExprStatementAST import *
+from slicc.ast.FormalParamAST import *
+from slicc.ast.FuncCallExprAST import *
+from slicc.ast.FuncDeclAST import *
+from slicc.ast.IfStatementAST import *
+from slicc.ast.InPortDeclAST import *
+from slicc.ast.InfixOperatorExprAST import *
+from slicc.ast.LiteralExprAST import *
+from slicc.ast.MachineAST import *
+from slicc.ast.MemberExprAST import *
+from slicc.ast.MethodCallExprAST import *
+from slicc.ast.NewExprAST import *
+from slicc.ast.ObjDeclAST import *
+from slicc.ast.OutPortDeclAST import *
+from slicc.ast.PairAST import *
+from slicc.ast.PairListAST import *
+from slicc.ast.PeekStatementAST import *
+from slicc.ast.ReturnStatementAST import *
+from slicc.ast.StatementAST import *
+from slicc.ast.StatementListAST import *
+from slicc.ast.TransitionDeclAST import *
+from slicc.ast.TypeAST import *
+from slicc.ast.TypeDeclAST import *
+from slicc.ast.TypeFieldAST import *
+from slicc.ast.TypeFieldEnumAST import *
+from slicc.ast.TypeFieldMemberAST import *
+from slicc.ast.TypeFieldMethodAST import *
+from slicc.ast.VarExprAST import *
diff --git a/src/mem/slicc/generate/__init__.py b/src/mem/slicc/generate/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/mem/slicc/generate/__init__.py
diff --git a/src/mem/slicc/generate/dot.py b/src/mem/slicc/generate/dot.py
new file mode 100644
index 000000000..762658983
--- /dev/null
+++ b/src/mem/slicc/generate/dot.py
@@ -0,0 +1,42 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.util.code_formatter import code_formatter
+
+def printDotty(sm, code):
+ code('digraph ${{sm.getIdent()}} {')
+ code.indent()
+ for t in sm.transitions:
+ # Don't print ignored transitions
+ if t.getActionShorthands() in ("--", "z"):
+ continue
+
+ code('${{t.getStateShorthand()}} -> ${{t.getNextStateShorthand()}')
+ code(' [label="${{t.getEventShorthand()}}/${{t.getActionShorthands()}}"')
+ code.dedent()
+ code('}')
+
diff --git a/src/mem/slicc/generate/html.py b/src/mem/slicc/generate/html.py
new file mode 100644
index 000000000..53252ce3c
--- /dev/null
+++ b/src/mem/slicc/generate/html.py
@@ -0,0 +1,80 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.util.code_formatter import code_formatter
+
+def createSymbol(symbol, title):
+ code = code_formatter()
+ code('''<HTML><BODY><BIG>
+$title:
+${{formatShorthand(symbol.short)}} - ${{symbol.desc}}</BIG></BODY></HTML>''')
+ return code
+
+def formatShorthand(short):
+ munged_shorthand = ""
+ mode_is_normal = True
+
+ # -- Walk over the string, processing superscript directives
+ gen = enumerate(short)
+ for i,c in gen:
+ if c == '!':
+ # -- Reached logical end of shorthand name
+ break
+ elif c == '_':
+ munged_shorthand += " "
+ elif c == '^':
+ # -- Process super/subscript formatting
+ mode_is_normal = not mode_is_normal
+ if mode_is_normal:
+ # -- Back to normal mode
+ munged_shorthand += "</SUP>"
+ else:
+ # -- Going to superscript mode
+ munged_shorthand += "<SUP>"
+ elif c == '\\':
+ # -- Process Symbol character set
+ if i + 1 < len(short):
+ # -- Proceed to next char. Yes I know that changing
+ # the loop var is ugly!
+ i,c = gen.next()
+ munged_shorthand += "<B><FONT size=+1>"
+ munged_shorthand += c
+ munged_shorthand += "</FONT></B>"
+ else:
+ # -- FIXME: Add line number info later
+ panic("Encountered a `\\` without anything following it!")
+ else:
+ # -- Pass on un-munged
+ munged_shorthand += c
+
+ # -- Do any other munging
+ if not mode_is_normal:
+ # -- Back to normal mode
+ munged_shorthand += "</SUP>"
+
+ return munged_shorthand
+
diff --git a/src/mem/slicc/generate/tex.py b/src/mem/slicc/generate/tex.py
new file mode 100644
index 000000000..97c63ebc6
--- /dev/null
+++ b/src/mem/slicc/generate/tex.py
@@ -0,0 +1,71 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.util.code_formatter import code_formatter
+
+class tex_formatter(code_formatter):
+ braced = "<>"
+ double_braced = "<<>>"
+
+def printTexTable(sm, code):
+ tex = tex_formatter()
+ tex(r'''
+%& latex
+\documentclass[12pt]{article}
+\usepackage{graphics}
+\begin{document}
+\begin{tabular}{|l||$<<"l" * len(sm.events)>>|} \hline
+''')
+
+ for event in sm.events:
+ code(r" & \rotatebox{90}{$<<event.short>>}")
+ tex(r'\\ \hline \hline')
+
+ for state in sm.states:
+ state_str = state.short
+ for event in sm.events:
+ state_str += ' & '
+ trans = sm.get_transition(state, event)
+ if trans:
+ actions = trans.getActionShorthands()
+ # FIXME: should compare index, not the string
+ if trans.getNextStateShorthand() != state.short:
+ nextState = trans.getNextStateShorthand()
+ else:
+ nextState = ""
+ state_str += actions
+ if nextState and actions:
+ state_str += '/'
+ state_str += nextState
+ tex(r'$0 \\', state_str)
+ tex(r'''
+\hline
+\end{tabular}
+\end{document}
+''')
+
+ code.append(tex)
diff --git a/src/mem/slicc/generator/html_gen.cc b/src/mem/slicc/generator/html_gen.cc
deleted file mode 100644
index 2d35dccb6..000000000
--- a/src/mem/slicc/generator/html_gen.cc
+++ /dev/null
@@ -1,125 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * html_gen.C
- *
- * Description: See html_gen.hh
- *
- * $Id: html_gen.C,v 3.4 2004/01/31 20:46:50 milo Exp $
- *
- * */
-
-#include "mem/slicc/generator/html_gen.hh"
-#include "mem/slicc/generator/fileio.hh"
-#include "mem/slicc/symbols/SymbolTable.hh"
-
-string formatHTMLShorthand(const string shorthand);
-
-
-void createHTMLSymbol(const Symbol& sym, string title, ostream& out)
-{
- out << "<HTML><BODY><BIG>" << endl;
- out << title << ": " << endl;
- out << formatHTMLShorthand(sym.getShorthand()) << " - ";
- out << sym.getDescription();
- out << "</BIG></BODY></HTML>" << endl;
-}
-
-void createHTMLindex(string title, ostream& out)
-{
- out << "<html>" << endl;
- out << "<head>" << endl;
- out << "<title>" << title << "</title>" << endl;
- out << "</head>" << endl;
- out << "<frameset rows=\"*,30\">" << endl;
- Vector<StateMachine*> machine_vec = g_sym_table.getStateMachines();
- if (machine_vec.size() > 1) {
- string machine = machine_vec[0]->getIdent();
- out << " <frame name=\"Table\" src=\"" << machine << "_table.html\">" << endl;
- } else {
- out << " <frame name=\"Table\" src=\"empty.html\">" << endl;
- }
-
- out << " <frame name=\"Status\" src=\"empty.html\">" << endl;
- out << "</frameset>" << endl;
- out << "</html>" << endl;
-}
-
-string formatHTMLShorthand(const string shorthand)
-{
- string munged_shorthand = "";
- bool mode_is_normal = true;
-
- // -- Walk over the string, processing superscript directives
- for(unsigned int i = 0; i < shorthand.length(); i++) {
- if(shorthand[i] == '!') {
- // -- Reached logical end of shorthand name
- break;
- } else if( shorthand[i] == '_') {
- munged_shorthand += " ";
- } else if( shorthand[i] == '^') {
- // -- Process super/subscript formatting
- mode_is_normal = !mode_is_normal;
- if(mode_is_normal) {
- // -- Back to normal mode
- munged_shorthand += "</SUP>";
- } else {
- // -- Going to superscript mode
- munged_shorthand += "<SUP>";
- }
- } else if(shorthand[i] == '\\') {
- // -- Process Symbol character set
- if((i + 1) < shorthand.length()) {
- i++; // -- Proceed to next char. Yes I know that changing the loop var is ugly!
- munged_shorthand += "<B><FONT size=+1>";
- munged_shorthand += shorthand[i];
- munged_shorthand += "</FONT></B>";
- } else {
- // -- FIXME: Add line number info later
- cerr << "Encountered a `\\` without anything following it!" << endl;
- exit( -1 );
- }
- } else {
- // -- Pass on un-munged
- munged_shorthand += shorthand[i];
- }
- } // -- end for all characters in shorthand
-
- // -- Do any other munging
- if(!mode_is_normal) {
- // -- Back to normal mode
- munged_shorthand += "</SUP>";
- }
-
- // -- Return the formatted shorthand name
- return munged_shorthand;
-}
-
-
diff --git a/src/mem/slicc/generator/html_gen.hh b/src/mem/slicc/generator/html_gen.hh
deleted file mode 100644
index 6b1f8ea92..000000000
--- a/src/mem/slicc/generator/html_gen.hh
+++ /dev/null
@@ -1,49 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * html_gen.hh
- *
- * Description:
- *
- * $Id: html_gen.hh,v 3.1 2001/12/12 01:00:35 milo Exp $
- *
- * */
-
-#ifndef HTML_GEN_H
-#define HTML_GEN_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/symbols/StateMachine.hh"
-
-string formatHTMLShorthand(const string shorthand);
-void createHTMLindex(string title, ostream& out);
-void createHTMLSymbol(const Symbol& sym, string title, ostream& out);
-
-#endif //HTML_GEN_H
diff --git a/src/mem/slicc/generator/mif_gen.cc b/src/mem/slicc/generator/mif_gen.cc
deleted file mode 100644
index 2dca149b4..000000000
--- a/src/mem/slicc/generator/mif_gen.cc
+++ /dev/null
@@ -1,1718 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- *
- */
-
-#include "mem/slicc/generator/mif_gen.hh"
-#include "mem/slicc/symbols/State.hh"
-#include "mem/slicc/symbols/Event.hh"
-#include "mem/slicc/symbols/Action.hh"
-#include "mem/slicc/symbols/Transition.hh"
-
-// -- Helper functions
-string formatShorthand(const string shorthand);
-string formatCellRuling(const string shorthand);
-
-void printStateTableMIF(const StateMachine& sm, ostream& out)
-{
- const string mif_prolog1 =
-"<MIFFile 5.50> # Generated by Multifacet MIF Mungers Inc\n\
-<Tbls\n\
- <Tbl\n\
- <TblID 1>\n\
- <TblTag `Format A'>\n\
- <TblFormat\n\
-\n\
- <TblAlignment Center>\n\
-\n\
- # <TblXColumnNum 0>\n\
- <TblXColumnRuling `Medium'>\n\
-\n\
- <TblLRuling `Medium'>\n\
- <TblRRuling `Medium'>\n\
- <TblTRuling `Medium'>\n\
- <TblBRuling `Medium'>\n\
-\n\
- <TblColumn\n\
- <TblColumnNum 0>\n\
- <TblColumnWidth 0.51\">\n\
- <TblColumnH\n\
- <PgfTag `CellHeading'>\n\
- > # end of TblColumnH\n\
- <TblColumnBody\n\
- <PgfTag `CellBody'>\n\
- > # end of TblColumnBody\n\
- <TblColumnF\n\
- <PgfTag `CellHeading'>\n\
- > # end of TblColumnF\n\
- > # end of TblColumn\n\
- <TblColumn\n\
- <TblColumnNum 1>\n\
- <TblColumnWidth 0.51\">\n\
- <TblColumnH\n\
- <PgfTag `CellHeading'>\n\
- > # end of TblColumnH\n\
- <TblColumnBody\n\
- <PgfTag `CellBody'>\n\
- > # end of TblColumnBody\n\
- <TblColumnF\n\
- <PgfTag `CellHeading'>\n\
- > # end of TblColumnF\n\
- > # end of TblColumn\n\
- > # end of TblFormat\n\
-\n\
- <TblNumColumns 2>\n\
- <TblColumnWidth 0.51\">\n\
- <TblColumnWidth 6.00\">\n\
- <TblTitle\n\
- <TblTitleContent\n\
- <Para\n\
- <PgfTag `TableTitle'>\n\
- <Pgf\n\
- <PgfAlignment Center>\n\
- <PgfFont \n\
- <FTag `'>\n\
- <FFamily `Times'>\n\
- <FVar `Regular'>\n\
- <FWeight `Regular'>\n\
- <FAngle `Regular'>\n\
- <FPostScriptName `Times-Roman'>\n\
- <FEncoding `FrameRoman'>\n\
- <FSize 11.0 pt>\n\
- <FUnderlining FNoUnderlining>\n\
- <FOverline No>\n\
- <FStrike No>\n\
- <FChangeBar No>\n\
- <FOutline No>\n\
- <FShadow No>\n\
- <FPairKern Yes>\n\
- <FTsume No>\n\
- <FCase FAsTyped>\n\
- <FPosition FNormal>\n\
- <FDX 0.0%>\n\
- <FDY 0.0%>\n\
- <FDW 0.0%>\n\
- <FStretch 100.0%>\n\
- <FLanguage USEnglish>\n\
- <FLocked No>\n\
- <FSeparation 0>\n\
- <FColor `Black'>\n\
- > # end of PgfFont\n\
- > # end of Pgf\n\
- <PgfNumString `TABLE 1. '>\n\
- <ParaLine\n\
- <Marker\n\
- <MType 9>\n\
- <MTypeName `Cross-Ref'>\n\
- <MCurrPage `1'>\n\
- > # end of Marker\n\
- <String `";
-
- const string mif_prolog2 =
- "'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of TblTitleContent\n\
- > # end of TblTitle\n\
-\n\
- <TblH\n\
- <Row\n\
- <RowMaxHeight 14.0\">\n\
- <RowHeight 0.44444\">\n\
- <Cell\n\
- <CellLRuling `Medium'>\n\
- <CellBRuling `Medium'>\n\
- <CellRRuling `Medium'>\n\
- <CellTRuling `Medium'>\n\
- <CellContent\n\
- <Para\n\
- <PgfTag `CellHeading'>\n\
- <Pgf\n\
- <PgfAlignment Center>\n\
- <PgfFont \n\
- <FTag `'>\n\
- <FFamily `Times'>\n\
- <FVar `Regular'>\n\
- <FWeight `Regular'>\n\
- <FAngle `Regular'>\n\
- <FPostScriptName `Times-Roman'>\n\
- <FEncoding `FrameRoman'>\n\
- <FSize 11.0 pt>\n\
- <FUnderlining FNoUnderlining>\n\
- <FOverline No>\n\
- <FStrike No>\n\
- <FChangeBar No>\n\
- <FOutline No>\n\
- <FShadow No>\n\
- <FPairKern Yes>\n\
- <FTsume No>\n\
- <FCase FAsTyped>\n\
- <FPosition FNormal>\n\
- <FDX 0.0%>\n\
- <FDY 0.0%>\n\
- <FDW 0.0%>\n\
- <FStretch 100.0%>\n\
- <FLanguage USEnglish>\n\
- <FLocked No>\n\
- <FSeparation 0>\n\
- <FColor `Black'>\n\
- > # end of PgfFont\n\
- >\n\
- <ParaLine\n\
- <String `State'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of CellContent\n\
- > # end of Cell\n\
- <Cell\n\
- <CellLRuling `Medium'>\n\
- <CellBRuling `Medium'>\n\
- <CellRRuling `Medium'>\n\
- <CellTRuling `Medium'>\n\
- <CellContent\n\
- <Para\n\
- <PgfTag `CellHeading'>\n\
- <PgfFont \n\
- <FTag `'>\n\
- <FFamily `Times'>\n\
- <FVar `Regular'>\n\
- <FWeight `Regular'>\n\
- <FAngle `Regular'>\n\
- <FPostScriptName `Times-Roman'>\n\
- <FEncoding `FrameRoman'>\n\
- <FSize 11.0 pt>\n\
- <FUnderlining FNoUnderlining>\n\
- <FOverline No>\n\
- <FStrike No>\n\
- <FChangeBar No>\n\
- <FOutline No>\n\
- <FShadow No>\n\
- <FPairKern Yes>\n\
- <FTsume No>\n\
- <FCase FAsTyped>\n\
- <FPosition FNormal>\n\
- <FDX 0.0%>\n\
- <FDY 0.0%>\n\
- <FDW 0.0%>\n\
- <FStretch 100.0%>\n\
- <FLanguage USEnglish>\n\
- <FLocked No>\n\
- <FSeparation 0>\n\
- <FColor `Black'>\n\
- > # end of PgfFont\n\
- <ParaLine\n\
- <String `Description'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of CellContent\n\
- > # end of Cell\n\
- > # end of Row\n\
- > # end of TblH\n\
-\n\
- <TblBody\n\
-";
-
- const string row_before_state =
-" <Row\n\
- <RowMaxHeight 14.0\">\n\
- <RowHeight 0.22222\">\n\
- <Cell\n\
- <CellContent\n\
- <Para\n\
- <PgfTag `CellBody'>\n\
- <Pgf\n\
- <PgfAlignment Center>\n\
- <PgfFont \n\
- <FTag `'>\n\
- <FFamily `Times'>\n\
- <FVar `Regular'>\n\
- <FWeight `Regular'>\n\
- <FAngle `Regular'>\n\
- <FPostScriptName `Times-Roman'>\n\
- <FEncoding `FrameRoman'>\n\
- <FSize 11.0 pt>\n\
- <FUnderlining FNoUnderlining>\n\
- <FOverline No>\n\
- <FStrike No>\n\
- <FChangeBar No>\n\
- <FOutline No>\n\
- <FShadow No>\n\
- <FPairKern Yes>\n\
- <FTsume No>\n\
- <FCase FAsTyped>\n\
- <FPosition FNormal>\n\
- <FDX 0.0%>\n\
- <FDY 0.0%>\n\
- <FDW 0.0%>\n\
- <FStretch 100.0%>\n\
- <FLanguage USEnglish>\n\
- <FLocked No>\n\
- <FSeparation 0>\n\
- <FColor `Black'>\n\
- > # end of PgfFont\n\
- >\n\
- <ParaLine\n\
- <String `";
-
- const string row_between_state_desc =
- "'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of CellContent\n\
- > # end of Cell\n\
- <Cell\n\
- <CellContent\n\
- <Para\n\
- <PgfTag `CellBody'>\n\
- <ParaLine\n\
- <String `";
-
- const string row_after_desc =
- "'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of CellContent\n\
- > # end of Cell\n\
- > # end of Row\n\
-";
-
- const string mif_epilog =
-" > # end of TblBody\n\
- > # end of Tbl\n\
-> # end of Tbls\n\
-\n\
- <Para\n\
- <ParaLine\n\
- <ATbl 1>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
-\n\
-# End of MIFFile\n\
-";
-
- out << mif_prolog1;
- out << formatShorthand( sm.getShorthand() );
- out << " states";
- out << mif_prolog2;
-
- for( int i = 0; i < sm.numStates(); i++ )
- {
- out << row_before_state;
- out << formatShorthand( sm.getState( i ).getShorthand() );
- out << row_between_state_desc;
- out << sm.getState( i ).getDescription();
- out << row_after_desc;
- }
-
- out << mif_epilog;
-}
-
-
-void printEventTableMIF(const StateMachine& sm, ostream& out)
-{
- const string mif_prolog1 =
-"<MIFFile 5.50> # Generated by Multifacet MIF Mungers Inc\n\
-<Tbls\n\
- <Tbl\n\
- <TblID 1>\n\
- <TblTag `Format A'>\n\
- <TblFormat\n\
-\n\
- <TblAlignment Center>\n\
-\n\
- # <TblXColumnNum 0>\n\
- <TblXColumnRuling `Medium'>\n\
-\n\
- <TblLRuling `Medium'>\n\
- <TblRRuling `Medium'>\n\
- <TblTRuling `Medium'>\n\
- <TblBRuling `Medium'>\n\
-\n\
- <TblColumn\n\
- <TblColumnNum 0>\n\
- <TblColumnWidth 0.51\">\n\
- <TblColumnH\n\
- <PgfTag `CellHeading'>\n\
- > # end of TblColumnH\n\
- <TblColumnBody\n\
- <PgfTag `CellBody'>\n\
- > # end of TblColumnBody\n\
- <TblColumnF\n\
- <PgfTag `CellHeading'>\n\
- > # end of TblColumnF\n\
- > # end of TblColumn\n\
- <TblColumn\n\
- <TblColumnNum 1>\n\
- <TblColumnWidth 0.51\">\n\
- <TblColumnH\n\
- <PgfTag `CellHeading'>\n\
- > # end of TblColumnH\n\
- <TblColumnBody\n\
- <PgfTag `CellBody'>\n\
- > # end of TblColumnBody\n\
- <TblColumnF\n\
- <PgfTag `CellHeading'>\n\
- > # end of TblColumnF\n\
- > # end of TblColumn\n\
- > # end of TblFormat\n\
-\n\
- <TblNumColumns 2>\n\
- <TblColumnWidth 0.51\">\n\
- <TblColumnWidth 6.00\">\n\
- <TblTitle\n\
- <TblTitleContent\n\
- <Para\n\
- <PgfTag `TableTitle'>\n\
- <Pgf\n\
- <PgfAlignment Center>\n\
- <PgfFont \n\
- <FTag `'>\n\
- <FFamily `Times'>\n\
- <FVar `Regular'>\n\
- <FWeight `Regular'>\n\
- <FAngle `Regular'>\n\
- <FPostScriptName `Times-Roman'>\n\
- <FEncoding `FrameRoman'>\n\
- <FSize 11.0 pt>\n\
- <FUnderlining FNoUnderlining>\n\
- <FOverline No>\n\
- <FStrike No>\n\
- <FChangeBar No>\n\
- <FOutline No>\n\
- <FShadow No>\n\
- <FPairKern Yes>\n\
- <FTsume No>\n\
- <FCase FAsTyped>\n\
- <FPosition FNormal>\n\
- <FDX 0.0%>\n\
- <FDY 0.0%>\n\
- <FDW 0.0%>\n\
- <FStretch 100.0%>\n\
- <FLanguage USEnglish>\n\
- <FLocked No>\n\
- <FSeparation 0>\n\
- <FColor `Black'>\n\
- > # end of PgfFont\n\
- > # end of Pgf\n\
- <PgfNumString `TABLE 1. '>\n\
- <ParaLine\n\
- <Marker\n\
- <MType 9>\n\
- <MTypeName `Cross-Ref'>\n\
- <MCurrPage `1'>\n\
- > # end of Marker\n\
- <String `";
- const string mif_prolog2 =
-"'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of TblTitleContent\n\
- > # end of TblTitle\n\
-\n\
- <TblH\n\
- <Row\n\
- <RowMaxHeight 14.0\">\n\
- <RowHeight 0.44444\">\n\
- <Cell\n\
- <CellLRuling `Medium'>\n\
- <CellBRuling `Medium'>\n\
- <CellRRuling `Medium'>\n\
- <CellTRuling `Medium'>\n\
- <CellContent\n\
- <Para\n\
- <PgfTag `CellHeading'>\n\
- <PgfFont \n\
- <FTag `'>\n\
- <FFamily `Times'>\n\
- <FVar `Regular'>\n\
- <FWeight `Regular'>\n\
- <FAngle `Regular'>\n\
- <FPostScriptName `Times-Roman'>\n\
- <FEncoding `FrameRoman'>\n\
- <FSize 11.0 pt>\n\
- <FUnderlining FNoUnderlining>\n\
- <FOverline No>\n\
- <FStrike No>\n\
- <FChangeBar No>\n\
- <FOutline No>\n\
- <FShadow No>\n\
- <FPairKern Yes>\n\
- <FTsume No>\n\
- <FCase FAsTyped>\n\
- <FPosition FNormal>\n\
- <FDX 0.0%>\n\
- <FDY 0.0%>\n\
- <FDW 0.0%>\n\
- <FStretch 100.0%>\n\
- <FLanguage USEnglish>\n\
- <FLocked No>\n\
- <FSeparation 0>\n\
- <FColor `Black'>\n\
- > # end of PgfFont\n\
- <Pgf\n\
- <PgfAlignment Center>\n\
- <PgfFont \n\
- <FTag `'>\n\
- <FFamily `Times'>\n\
- <FVar `Regular'>\n\
- <FWeight `Regular'>\n\
- <FAngle `Regular'>\n\
- <FPostScriptName `Times-Roman'>\n\
- <FEncoding `FrameRoman'>\n\
- <FSize 11.0 pt>\n\
- <FUnderlining FNoUnderlining>\n\
- <FOverline No>\n\
- <FStrike No>\n\
- <FChangeBar No>\n\
- <FOutline No>\n\
- <FShadow No>\n\
- <FPairKern Yes>\n\
- <FTsume No>\n\
- <FCase FAsTyped>\n\
- <FPosition FNormal>\n\
- <FDX 0.0%>\n\
- <FDY 0.0%>\n\
- <FDW 0.0%>\n\
- <FStretch 100.0%>\n\
- <FLanguage USEnglish>\n\
- <FLocked No>\n\
- <FSeparation 0>\n\
- <FColor `Black'>\n\
- > # end of PgfFont\n\
- >\n\
- <ParaLine\n\
- <String `Event'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of CellContent\n\
- > # end of Cell\n\
- <Cell\n\
- <CellLRuling `Medium'>\n\
- <CellBRuling `Medium'>\n\
- <CellRRuling `Medium'>\n\
- <CellTRuling `Medium'>\n\
- <CellContent\n\
- <Para\n\
- <PgfTag `CellHeading'>\n\
- <ParaLine\n\
- <String `Description'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of CellContent\n\
- > # end of Cell\n\
- > # end of Row\n\
- > # end of TblH\n\
-\n\
- <TblBody\n\
-";
-
- const string row_before_event =
-" <Row\n\
- <RowMaxHeight 14.0\">\n\
- <RowHeight 0.22222\">\n\
- <Cell\n\
- <CellContent\n\
- <Para\n\
- <PgfTag `CellBody'>\n\
- <Pgf\n\
- <PgfAlignment Center>\n\
- <PgfFont \n\
- <FTag `'>\n\
- <FFamily `Times'>\n\
- <FVar `Regular'>\n\
- <FWeight `Regular'>\n\
- <FAngle `Regular'>\n\
- <FPostScriptName `Times-Roman'>\n\
- <FEncoding `FrameRoman'>\n\
- <FSize 11.0 pt>\n\
- <FUnderlining FNoUnderlining>\n\
- <FOverline No>\n\
- <FStrike No>\n\
- <FChangeBar No>\n\
- <FOutline No>\n\
- <FShadow No>\n\
- <FPairKern Yes>\n\
- <FTsume No>\n\
- <FCase FAsTyped>\n\
- <FPosition FNormal>\n\
- <FDX 0.0%>\n\
- <FDY 0.0%>\n\
- <FDW 0.0%>\n\
- <FStretch 100.0%>\n\
- <FLanguage USEnglish>\n\
- <FLocked No>\n\
- <FSeparation 0>\n\
- <FColor `Black'>\n\
- > # end of PgfFont\n\
- >\n\
- <ParaLine\n\
- <String `";
-
- const string row_between_event_desc =
- "'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of CellContent\n\
- > # end of Cell\n\
- <Cell\n\
- <CellContent\n\
- <Para\n\
- <PgfTag `CellBody'>\n\
- <ParaLine\n\
- <String `";
-
- const string row_after_desc =
- "'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of CellContent\n\
- > # end of Cell\n\
- > # end of Row\n\
-";
-
- const string mif_epilog =
-" > # end of TblBody\n\
- > # end of Tbl\n\
-> # end of Tbls\n\
-\n\
- <Para\n\
- <ParaLine\n\
- <ATbl 1>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
-\n\
-# End of MIFFile\n\
-";
-
- out << mif_prolog1;
- out << formatShorthand( sm.getShorthand() );
- out << " events";
- out << mif_prolog2;
-
- for( int i = 0; i < sm.numEvents(); i++ )
- {
- out << row_before_event;
- out << formatShorthand( sm.getEvent( i ).getShorthand() );
- out << row_between_event_desc;
- out << sm.getEvent( i ).getDescription();
- out << row_after_desc;
- }
-
- out << mif_epilog;
-}
-
-
-void printActionTableMIF(const StateMachine& sm, ostream& out)
-{
- const string mif_prolog1 =
-"<MIFFile 5.50> # Generated by Multifacet MIF Mungers Inc\n\
-<Tbls\n\
- <Tbl\n\
- <TblID 1>\n\
- <TblTag `Format A'>\n\
- <TblFormat\n\
-\n\
- <TblAlignment Center>\n\
-\n\
- # <TblXColumnNum 0>\n\
- <TblXColumnRuling `Medium'>\n\
-\n\
- <TblLRuling `Medium'>\n\
- <TblRRuling `Medium'>\n\
- <TblTRuling `Medium'>\n\
- <TblBRuling `Medium'>\n\
-\n\
- <TblColumn\n\
- <TblColumnNum 0>\n\
- <TblColumnWidth 0.51\">\n\
- <TblColumnH\n\
- <PgfTag `CellHeading'>\n\
- > # end of TblColumnH\n\
- <TblColumnBody\n\
- <PgfTag `CellBody'>\n\
- > # end of TblColumnBody\n\
- <TblColumnF\n\
- <PgfTag `CellHeading'>\n\
- > # end of TblColumnF\n\
- > # end of TblColumn\n\
- <TblColumn\n\
- <TblColumnNum 1>\n\
- <TblColumnWidth 0.51\">\n\
- <TblColumnH\n\
- <PgfTag `CellHeading'>\n\
- > # end of TblColumnH\n\
- <TblColumnBody\n\
- <PgfTag `CellBody'>\n\
- > # end of TblColumnBody\n\
- <TblColumnF\n\
- <PgfTag `CellHeading'>\n\
- > # end of TblColumnF\n\
- > # end of TblColumn\n\
- > # end of TblFormat\n\
-\n\
- <TblNumColumns 2>\n\
- <TblColumnWidth 0.51\">\n\
- <TblColumnWidth 6.00\">\n\
- <TblTitle\n\
- <TblTitleContent\n\
- <Para\n\
- <PgfTag `TableTitle'>\n\
- <Pgf\n\
- <PgfAlignment Center>\n\
- <PgfFont \n\
- <FTag `'>\n\
- <FFamily `Times'>\n\
- <FVar `Regular'>\n\
- <FWeight `Regular'>\n\
- <FAngle `Regular'>\n\
- <FPostScriptName `Times-Roman'>\n\
- <FEncoding `FrameRoman'>\n\
- <FSize 11.0 pt>\n\
- <FUnderlining FNoUnderlining>\n\
- <FOverline No>\n\
- <FStrike No>\n\
- <FChangeBar No>\n\
- <FOutline No>\n\
- <FShadow No>\n\
- <FPairKern Yes>\n\
- <FTsume No>\n\
- <FCase FAsTyped>\n\
- <FPosition FNormal>\n\
- <FDX 0.0%>\n\
- <FDY 0.0%>\n\
- <FDW 0.0%>\n\
- <FStretch 100.0%>\n\
- <FLanguage USEnglish>\n\
- <FLocked No>\n\
- <FSeparation 0>\n\
- <FColor `Black'>\n\
- > # end of PgfFont\n\
- > # end of Pgf\n\
- <PgfNumString `TABLE 1. '>\n\
- <ParaLine\n\
- <Marker\n\
- <MType 9>\n\
- <MTypeName `Cross-Ref'>\n\
- <MCurrPage `1'>\n\
- > # end of Marker\n\
- <String `";
- const string mif_prolog2 =
-"'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of TblTitleContent\n\
- > # end of TblTitle\n\
-\n\
- <TblH\n\
- <Row\n\
- <RowMaxHeight 14.0\">\n\
- <RowHeight 0.44444\">\n\
- <Cell\n\
- <CellLRuling `Medium'>\n\
- <CellBRuling `Medium'>\n\
- <CellRRuling `Medium'>\n\
- <CellTRuling `Medium'>\n\
- <CellContent\n\
- <Para\n\
- <PgfTag `CellHeading'>\n\
- <Pgf\n\
- <PgfAlignment Center>\n\
- <PgfFont \n\
- <FTag `'>\n\
- <FFamily `Times'>\n\
- <FVar `Regular'>\n\
- <FWeight `Regular'>\n\
- <FAngle `Regular'>\n\
- <FPostScriptName `Times-Roman'>\n\
- <FEncoding `FrameRoman'>\n\
- <FSize 11.0 pt>\n\
- <FUnderlining FNoUnderlining>\n\
- <FOverline No>\n\
- <FStrike No>\n\
- <FChangeBar No>\n\
- <FOutline No>\n\
- <FShadow No>\n\
- <FPairKern Yes>\n\
- <FTsume No>\n\
- <FCase FAsTyped>\n\
- <FPosition FNormal>\n\
- <FDX 0.0%>\n\
- <FDY 0.0%>\n\
- <FDW 0.0%>\n\
- <FStretch 100.0%>\n\
- <FLanguage USEnglish>\n\
- <FLocked No>\n\
- <FSeparation 0>\n\
- <FColor `Black'>\n\
- > # end of PgfFont\n\
- >\n\
- <ParaLine\n\
- <String `Action'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of CellContent\n\
- > # end of Cell\n\
- <Cell\n\
- <CellLRuling `Medium'>\n\
- <CellBRuling `Medium'>\n\
- <CellRRuling `Medium'>\n\
- <CellTRuling `Medium'>\n\
- <CellContent\n\
- <Para\n\
- <PgfTag `CellHeading'>\n\
- <ParaLine\n\
- <String `Description'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of CellContent\n\
- > # end of Cell\n\
- > # end of Row\n\
- > # end of TblH\n\
-\n\
- <TblBody\n\
-";
-
- const string row_before_action =
-" <Row\n\
- <RowMaxHeight 14.0\">\n\
- <RowHeight 0.22222\">\n\
- <Cell\n\
- <CellContent\n\
- <Para\n\
- <PgfTag `CellBody'>\n\
- <Pgf\n\
- <PgfAlignment Center>\n\
- <PgfFont \n\
- <FTag `'>\n\
- <FFamily `Times'>\n\
- <FVar `Regular'>\n\
- <FWeight `Regular'>\n\
- <FAngle `Regular'>\n\
- <FPostScriptName `Times-Roman'>\n\
- <FEncoding `FrameRoman'>\n\
- <FSize 11.0 pt>\n\
- <FUnderlining FNoUnderlining>\n\
- <FOverline No>\n\
- <FStrike No>\n\
- <FChangeBar No>\n\
- <FOutline No>\n\
- <FShadow No>\n\
- <FPairKern Yes>\n\
- <FTsume No>\n\
- <FCase FAsTyped>\n\
- <FPosition FNormal>\n\
- <FDX 0.0%>\n\
- <FDY 0.0%>\n\
- <FDW 0.0%>\n\
- <FStretch 100.0%>\n\
- <FLanguage USEnglish>\n\
- <FLocked No>\n\
- <FSeparation 0>\n\
- <FColor `Black'>\n\
- > # end of PgfFont\n\
- >\n\
- <ParaLine\n\
- <String `";
-
- const string row_between_action_desc =
- "'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of CellContent\n\
- > # end of Cell\n\
- <Cell\n\
- <CellContent\n\
- <Para\n\
- <PgfTag `CellBody'>\n\
- <ParaLine\n\
- <String `";
-
- const string row_after_desc =
- "'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of CellContent\n\
- > # end of Cell\n\
- > # end of Row\n\
-";
-
- const string mif_epilog =
-" > # end of TblBody\n\
- > # end of Tbl\n\
-> # end of Tbls\n\
-\n\
- <Para\n\
- <ParaLine\n\
- <ATbl 1>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
-\n\
-# End of MIFFile\n\
-";
-
- out << mif_prolog1;
- out << formatShorthand( sm.getShorthand() );
- out << " actions";
- out << mif_prolog2;
-
- for( int i = 0; i < sm.numActions(); i++ )
- {
- out << row_before_action;
- out << formatShorthand( sm.getAction( i ).getShorthand() );
- out << row_between_action_desc;
- out << sm.getAction( i ).getDescription();
- out << row_after_desc;
- }
-
- out << mif_epilog;
-}
-
-
-void printTransitionTableMIF(const StateMachine& sm, ostream& out)
-{
- const string mif_prolog =
-"<MIFFile 5.50> # Generated by Multifacet MIF Mungers Inc\n\
-<Tbls\n\
- <Tbl\n\
- <TblID 1>\n\
- <TblTag `Format A'>\n\
- <TblFormat\n\
-\n\
- <TblAlignment Center>\n\
-\n\
- # <TblXColumnNum 0>\n\
- <TblXColumnRuling `Medium'>\n\
-\n\
- <TblLRuling `Medium'>\n\
- <TblRRuling `Medium'>\n\
- <TblTRuling `Medium'>\n\
- <TblBRuling `Medium'>\n\
- \n\
-";
-
- const string tbl_fmt_before_col_num =
-" <TblColumn\n\
- <TblColumnNum ";
-
- const string tbl_fmt_after_col_num =
- ">\n\
- <TblColumnWidth 0.51\">\n\
- <TblColumnH\n\
- <PgfTag `CellHeading'>\n\
- > # end of TblColumnH\n\
- <TblColumnBody\n\
- <PgfTag `CellBody'>\n\
- > # end of TblColumnBody\n\
- <TblColumnF\n\
- <PgfTag `CellHeading'>\n\
- > # end of TblColumnF\n\
- > # end of TblColumn\n\
-";
-
- const string tbl_fmt_before_num_cols =
-" > # end of TblFormat\n\
-\n\
- <TblNumColumns ";
-
- const string tbl_fmt_each_col_width_begin =
- ">\n\
- <TblColumnWidth ";
-
- const string tbl_fmt_each_col_width_end = "\"";
-
- const string tbl_before_first_header1 =
- ">\n\
- <TblTitle\n\
- <TblTitleContent\n\
- <Para\n\
- <PgfTag `TableTitle'>\n\
- <Pgf\n\
- <PgfAlignment Center>\n\
- <PgfFont \n\
- <FTag `'>\n\
- <FFamily `Times'>\n\
- <FVar `Regular'>\n\
- <FWeight `Regular'>\n\
- <FAngle `Regular'>\n\
- <FPostScriptName `Times-Roman'>\n\
- <FEncoding `FrameRoman'>\n\
- <FSize 11.0 pt>\n\
- <FUnderlining FNoUnderlining>\n\
- <FOverline No>\n\
- <FStrike No>\n\
- <FChangeBar No>\n\
- <FOutline No>\n\
- <FShadow No>\n\
- <FPairKern Yes>\n\
- <FTsume No>\n\
- <FCase FAsTyped>\n\
- <FPosition FNormal>\n\
- <FDX 0.0%>\n\
- <FDY 0.0%>\n\
- <FDW 0.0%>\n\
- <FStretch 100.0%>\n\
- <FLanguage USEnglish>\n\
- <FLocked No>\n\
- <FSeparation 0>\n\
- <FColor `Black'>\n\
- > # end of PgfFont\n\
- > # end of Pgf\n\
- <PgfNumString `TABLE 1. '>\n\
- <ParaLine\n\
- <Marker\n\
- <MType 9>\n\
- <MTypeName `Cross-Ref'>\n\
- <MCurrPage `1'>\n\
- > # end of Marker\n\
- <String `";
-
- const string tbl_before_first_header2 =
- "'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of TblTitleContent\n\
- > # end of TblTitle\n\
-\n\
- <TblH\n\
- <Row\n\
- <RowMaxHeight 14.0\">\n\
- <RowHeight 0.44444\">";
-
- const string tbl_before_each_header =
-" <Cell\n\
- <CellLRuling `Medium'>\n\
- <CellBRuling `Medium'>\n\
- <CellRRuling `Medium'>\n\
- <CellTRuling `Medium'>\n\
- <CellContent\n\
- <Para\n\
- <PgfTag `CellHeading'>\n\
- <Pgf\n\
- <PgfAlignment Center>\n\
- <PgfFont \n\
- <FTag `'>\n\
- <FFamily `Times'>\n\
- <FVar `Regular'>\n\
- <FWeight `Regular'>\n\
- <FAngle `Regular'>\n\
- <FPostScriptName `Times-Roman'>\n\
- <FEncoding `FrameRoman'>\n\
- <FSize 11.0 pt>\n\
- <FUnderlining FNoUnderlining>\n\
- <FOverline No>\n\
- <FStrike No>\n\
- <FChangeBar No>\n\
- <FOutline No>\n\
- <FShadow No>\n\
- <FPairKern Yes>\n\
- <FTsume No>\n\
- <FCase FAsTyped>\n\
- <FPosition FNormal>\n\
- <FDX 0.0%>\n\
- <FDY 0.0%>\n\
- <FDW 0.0%>\n\
- <FStretch 100.0%>\n\
- <FLanguage USEnglish>\n\
- <FLocked No>\n\
- <FSeparation 0>\n\
- <FColor `Black'>\n\
- > # end of PgfFont\n\
- >\n\
- <ParaLine\n\
- <String `";
-
- const string tbl_before_each_rot_header =
-" <Cell\n\
- <CellLRuling `Medium'>\n\
- <CellBRuling `Medium'>\n\
- <CellRRuling `Medium'>\n\
- <CellTRuling `Medium'>\n\
- <CellAngle 270>\n\
- <CellContent\n\
- <Para\n\
- <PgfTag `CellHeading'>\n\
- <ParaLine\n\
- <String `";
-
- const string tbl_after_each_header =
- "'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of CellContent\n\
- > # end of Cell\n\
-";
-
- const string before_first_row =
-" > # end of Row\n\
- > # end of TblH\n\
-\n\
- <TblBody\n\
-";
-
- const string row_before_first_cell =
-" <Row\n\
- <RowMaxHeight 14.0\">\n\
- <RowHeight 0.22222\">";
-
- const string row_cell_before_ruling =
-" <Cell\n\
-";
-
- const string row_cell_before_contents =
-" <CellContent\n\
- <Para\n\
- <PgfTag `CellBody'>\n\
- <Pgf\n\
- <PgfAlignment Center>\n\
- <PgfFont \n\
- <FTag `'>\n\
- <FFamily `Times'>\n\
- <FVar `Regular'>\n\
- <FWeight `Regular'>\n\
- <FAngle `Regular'>\n\
- <FPostScriptName `Times-Roman'>\n\
- <FEncoding `FrameRoman'>\n\
- <FSize 11.0 pt>\n\
- <FUnderlining FNoUnderlining>\n\
- <FOverline No>\n\
- <FStrike No>\n\
- <FChangeBar No>\n\
- <FOutline No>\n\
- <FShadow No>\n\
- <FPairKern Yes>\n\
- <FTsume No>\n\
- <FCase FAsTyped>\n\
- <FPosition FNormal>\n\
- <FDX 0.0%>\n\
- <FDY 0.0%>\n\
- <FDW 0.0%>\n\
- <FStretch 100.0%>\n\
- <FLanguage USEnglish>\n\
- <FLocked No>\n\
- <FSeparation 0>\n\
- <FColor `Black'>\n\
- > # end of PgfFont\n\
- >\n\
- <ParaLine\n\
- <String `";
-
- const string row_cell_after_contents =
- "'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of CellContent\n\
- > # end of Cell\n\
-";
-
- const string row_empty_cell =
-" <CellFill 5>\n\
- <CellColor `Cyan'>\n\
- <CellContent\n\
- <Para\n\
- <PgfTag `CellBody'>\n\
- <ParaLine\n\
- <String `'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of CellContent\n\
- > # end of Cell\n\
-";
-
- const string row_after_last_cell =
-" > # end of Row\n\
-";
-
-
- const string mif_epilog =
-" > # end of TblBody\n\
- > # end of Tbl\n\
-> # end of Tbls\n\
-\n\
- <Para\n\
- <ParaLine\n\
- <ATbl 1>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
-\n\
-# End of MIFFile\n\
-";
-
- int i, j, num_rows, num_cols;
- string row_ruling;
- string col_ruling;
-
- num_rows = sm.numStates();
- num_cols = sm.numEvents() + 1;
-
- // -- Prolog
- out << mif_prolog;
-
- // -- Table format (for each column)
- for( i = 0; i < num_cols; i++ )
- {
- out << tbl_fmt_before_col_num;
- out << i;
- out << tbl_fmt_after_col_num;
- }
-
- // -- Spell out width of each column
-
- // -- FIXME: make following constants into parameters
- const float total_table_width = 7.5; // -- Total page width = 7.5" (portrait mode)
- const float min_col_width = 0.35; // -- Min col width (for legibility)
- const float max_col_width = 0.75; // -- Max col width (for aesthetics)
- float column_width;
-
- // -- Calculate column width and clamp it within a range
- column_width = total_table_width / num_cols;
- column_width = ((column_width < min_col_width)
- ? min_col_width
- : ((column_width > max_col_width)
- ? max_col_width
- : column_width));
-
- out << tbl_fmt_before_num_cols;
- out << num_cols;
- for( i = 0; i < num_cols; i++ )
- {
- out << tbl_fmt_each_col_width_begin << column_width << tbl_fmt_each_col_width_end;
- }
-
- // -- Column headers
- out << tbl_before_first_header1;
- out << formatShorthand( sm.getShorthand() );
- out << " transitions";
- out << tbl_before_first_header2;
-
- out << tbl_before_each_header;
- out << "State";
- out << tbl_after_each_header;
-
- for( i = 0; i < sm.numEvents(); i++ )
- {
- out << tbl_before_each_rot_header;
- out << formatShorthand( sm.getEvent(i).getShorthand() );
- out << tbl_after_each_header;
- }
- out << before_first_row;
-
-
- // -- Body of table
- for( i = 0; i < num_rows; i++ )
- {
- // -- Each row
- out << row_before_first_cell;
-
- // -- Figure out ruling
- if (sm.getState(i).existPair("format")) {
- row_ruling = formatCellRuling( sm.getState(i).lookupPair("format"));
- } else {
- row_ruling = "";
- }
-
- // -- First column = state
- out << row_cell_before_ruling;
- out << row_ruling;
- out << row_cell_before_contents;
- out << formatShorthand( sm.getState(i).getShorthand() );
- out << row_cell_after_contents;
-
- // -- One column for each event
- for( j = 0; j < sm.numEvents(); j++ )
- {
- const Transition* trans_ptr = sm.getTransPtr( i, j );
-
- // -- Figure out ruling
- if (sm.getEvent(j).existPair("format")) {
- col_ruling = formatCellRuling(sm.getEvent(j).lookupPair("format"));
- } else {
- col_ruling = "";
- }
-
- out << row_cell_before_ruling;
- out << row_ruling;
- out << col_ruling;
-
- if( trans_ptr != NULL )
- {
- string actions;
- string nextState;
-
- // -- Get the actions
- actions = formatShorthand( trans_ptr->getActionShorthands() );
-
- // -- Get the next state
- // FIXME: should compare index, not the string
- if (trans_ptr->getNextStateShorthand() !=
- sm.getState(i).getShorthand() )
- {
- nextState = formatShorthand( trans_ptr->getNextStateShorthand() );
- } else
- {
- nextState = "";
- }
-
- // -- Print out "actions/next-state"
- out << row_cell_before_contents;
- out << actions;
- if ((nextState.length() != 0) && (actions.length() != 0)) {
- out << "/";
- }
- out << nextState;
- out << row_cell_after_contents;
- }
- else
- {
- out << row_empty_cell;
- }
-
- }
-
- out << row_after_last_cell;
- }
-
- // -- Epilog
- out << mif_epilog;
-
-}
-/*
-void printTBETableMIF(const StateMachine& sm, const Vector<Field>& fields, ostream& out)
-{
- const string mif_prolog1 =
-"<MIFFile 5.50> # Generated by Multifacet MIF Mungers Inc\n\
-<Tbls\n\
- <Tbl\n\
- <TblID 1>\n\
- <TblTag `Format A'>\n\
- <TblFormat\n\
-\n\
- <TblAlignment Center>\n\
-\n\
- # # <TblXColumnNum 0>\n\
- <TblXColumnRuling `Medium'>\n\
-\n\
- <TblLRuling `Medium'>\n\
- <TblRRuling `Medium'>\n\
- <TblTRuling `Medium'>\n\
- <TblBRuling `Medium'>\n\
-\n\
- <TblColumn\n\
- <TblColumnNum 0>\n\
- <TblColumnWidth 0.51\">\n\
- <TblColumnH\n\
- <PgfTag `CellHeading'>\n\
- > # end of TblColumnH\n\
- <TblColumnBody\n\
- <PgfTag `CellBody'>\n\
- > # end of TblColumnBody\n\
- <TblColumnF\n\
- <PgfTag `CellHeading'>\n\
- > # end of TblColumnF\n\
- > # end of TblColumn\n\
- <TblColumn\n\
- <TblColumnNum 1>\n\
- <TblColumnWidth 0.51\">\n\
- <TblColumnH\n\
- <PgfTag `CellHeading'>\n\
- > # end of TblColumnH\n\
- <TblColumnBody\n\
- <PgfTag `CellBody'>\n\
- > # end of TblColumnBody\n\
- <TblColumnF\n\
- <PgfTag `CellHeading'>\n\
- > # end of TblColumnF\n\
- > # end of TblColumn\n\
- > # end of TblFormat\n\
-\n\
- <TblNumColumns 2>\n\
- <TblColumnWidth 0.51\">\n\
- <TblColumnWidth 6.00\">\n\
- <TblTitle\n\
- <TblTitleContent\n\
- <Para\n\
- <PgfTag `TableTitle'>\n\
- <Pgf\n\
- <PgfAlignment Center>\n\
- <PgfFont \n\
- <FTag `'>\n\
- <FFamily `Times'>\n\
- <FVar `Regular'>\n\
- <FWeight `Regular'>\n\
- <FAngle `Regular'>\n\
- <FPostScriptName `Times-Roman'>\n\
- <FEncoding `FrameRoman'>\n\
- <FSize 11.0 pt>\n\
- <FUnderlining FNoUnderlining>\n\
- <FOverline No>\n\
- <FStrike No>\n\
- <FChangeBar No>\n\
- <FOutline No>\n\
- <FShadow No>\n\
- <FPairKern Yes>\n\
- <FTsume No>\n\
- <FCase FAsTyped>\n\
- <FPosition FNormal>\n\
- <FDX 0.0%>\n\
- <FDY 0.0%>\n\
- <FDW 0.0%>\n\
- <FStretch 100.0%>\n\
- <FLanguage USEnglish>\n\
- <FLocked No>\n\
- <FSeparation 0>\n\
- <FColor `Black'>\n\
- > # end of PgfFont\n\
- > # end of Pgf\n\
- <PgfNumString `TABLE 1. '>\n\
- <ParaLine\n\
- <Marker\n\
- <MType 9>\n\
- <MTypeName `Cross-Ref'>\n\
- <MCurrPage `1'>\n\
- > # end of Marker\n\
- <String `";
-
- const string mif_prolog2 =
- "'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of TblTitleContent\n\
- > # end of TblTitle\n\
-\n\
- <TblH\n\
- <Row\n\
- <RowMaxHeight 14.0\">\n\
- <RowHeight 0.44444\">\n\
- <Cell\n\
- <CellLRuling `Medium'>\n\
- <CellBRuling `Medium'>\n\
- <CellRRuling `Medium'>\n\
- <CellTRuling `Medium'>\n\
- <CellContent\n\
- <Para\n\
- <PgfTag `CellHeading'>\n\
- <Pgf\n\
- <PgfAlignment Center>\n\
- <PgfFont \n\
- <FTag `'>\n\
- <FFamily `Times'>\n\
- <FVar `Regular'>\n\
- <FWeight `Regular'>\n\
- <FAngle `Regular'>\n\
- <FPostScriptName `Times-Roman'>\n\
- <FEncoding `FrameRoman'>\n\
- <FSize 11.0 pt>\n\
- <FUnderlining FNoUnderlining>\n\
- <FOverline No>\n\
- <FStrike No>\n\
- <FChangeBar No>\n\
- <FOutline No>\n\
- <FShadow No>\n\
- <FPairKern Yes>\n\
- <FTsume No>\n\
- <FCase FAsTyped>\n\
- <FPosition FNormal>\n\
- <FDX 0.0%>\n\
- <FDY 0.0%>\n\
- <FDW 0.0%>\n\
- <FStretch 100.0%>\n\
- <FLanguage USEnglish>\n\
- <FLocked No>\n\
- <FSeparation 0>\n\
- <FColor `Black'>\n\
- > # end of PgfFont\n\
- >\n\
- <ParaLine\n\
- <String `Field'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of CellContent\n\
- > # end of Cell\n\
- <Cell\n\
- <CellLRuling `Medium'>\n\
- <CellBRuling `Medium'>\n\
- <CellRRuling `Medium'>\n\
- <CellTRuling `Medium'>\n\
- <CellContent\n\
- <Para\n\
- <PgfTag `CellHeading'>\n\
- <PgfFont \n\
- <FTag `'>\n\
- <FFamily `Times'>\n\
- <FVar `Regular'>\n\
- <FWeight `Regular'>\n\
- <FAngle `Regular'>\n\
- <FPostScriptName `Times-Roman'>\n\
- <FEncoding `FrameRoman'>\n\
- <FSize 11.0 pt>\n\
- <FUnderlining FNoUnderlining>\n\
- <FOverline No>\n\
- <FStrike No>\n\
- <FChangeBar No>\n\
- <FOutline No>\n\
- <FShadow No>\n\
- <FPairKern Yes>\n\
- <FTsume No>\n\
- <FCase FAsTyped>\n\
- <FPosition FNormal>\n\
- <FDX 0.0%>\n\
- <FDY 0.0%>\n\
- <FDW 0.0%>\n\
- <FStretch 100.0%>\n\
- <FLanguage USEnglish>\n\
- <FLocked No>\n\
- <FSeparation 0>\n\
- <FColor `Black'>\n\
- > # end of PgfFont\n\
- <ParaLine\n\
- <String `Description'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of CellContent\n\
- > # end of Cell\n\
- > # end of Row\n\
- > # end of TblH\n\
-\n\
- <TblBody\n\
-";
-
- const string row_before_state =
-" <Row\n\
- <RowMaxHeight 14.0\">\n\
- <RowHeight 0.22222\">\n\
- <Cell\n\
- <CellContent\n\
- <Para\n\
- <PgfTag `CellBody'>\n\
- <Pgf\n\
- <PgfAlignment Center>\n\
- <PgfFont \n\
- <FTag `'>\n\
- <FFamily `Times'>\n\
- <FVar `Regular'>\n\
- <FWeight `Regular'>\n\
- <FAngle `Regular'>\n\
- <FPostScriptName `Times-Roman'>\n\
- <FEncoding `FrameRoman'>\n\
- <FSize 11.0 pt>\n\
- <FUnderlining FNoUnderlining>\n\
- <FOverline No>\n\
- <FStrike No>\n\
- <FChangeBar No>\n\
- <FOutline No>\n\
- <FShadow No>\n\
- <FPairKern Yes>\n\
- <FTsume No>\n\
- <FCase FAsTyped>\n\
- <FPosition FNormal>\n\
- <FDX 0.0%>\n\
- <FDY 0.0%>\n\
- <FDW 0.0%>\n\
- <FStretch 100.0%>\n\
- <FLanguage USEnglish>\n\
- <FLocked No>\n\
- <FSeparation 0>\n\
- <FColor `Black'>\n\
- > # end of PgfFont\n\
- >\n\
- <ParaLine\n\
- <String `";
-
- const string row_between_state_desc =
- "'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of CellContent\n\
- > # end of Cell\n\
- <Cell\n\
- <CellContent\n\
- <Para\n\
- <PgfTag `CellBody'>\n\
- <ParaLine\n\
- <String `";
-
- const string row_after_desc =
- "'>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
- > # end of CellContent\n\
- > # end of Cell\n\
- > # end of Row\n\
-";
-
- const string mif_epilog =
-" > # end of TblBody\n\
- > # end of Tbl\n\
-> # end of Tbls\n\
-\n\
- <Para\n\
- <ParaLine\n\
- <ATbl 1>\n\
- > # end of ParaLine\n\
- > # end of Para\n\
-\n\
-# End of MIFFile\n\
-";
-
- out << mif_prolog1;
- out << sm.getShorthand();
- out << " TBE";
- out << mif_prolog2;
-
- for( int i = 0; i < fields.size(); i++ ) {
- out << row_before_state;
- out << formatShorthand(fields[i].getShorthand());
- out << row_between_state_desc;
- out << fields[i].getDescription();
- out << row_after_desc;
- }
-
- out << mif_epilog;
-}
-*/
-// --
-// -- Helper function to do some shorthand formatting (kludge before we
-// -- get the tuple attributes into the state machine language.
-// -- Current convention:
-// -- - each `_' indicates a toggle between normal mode and superscript
-// -- - each escaped (using `\') character indicates a letter formatted
-// -- using the Symbol character set. \a = alpha, \b = beta, \c = chi etc.
-// -- See the FrameMaker character sets manual in the Online Manuals.
-// -- - a `!' indicates extra stuff at the end which can be ignored (used
-// -- for determining cell ruling and so on)
-// --
-string formatShorthand(const string shorthand)
-{
- string munged_shorthand = "";
- bool mode_is_normal = true;
- const string mif_superscript = "'> <Font <FPosition FSuperscript> <FLocked No> > <String `";
- const string mif_normal = "'> <Font <FPosition FNormal> <FLocked No> > <String `";
- const string mif_symbol = "'> <Font <FFamily `Symbol'> <FPostScriptName `Symbol'> <FEncoding `FrameRoman'> <FLocked No> > <String `";
- const string mif_times = "'> <Font <FFamily `Times'> <FPostScriptName `Times-Roman'> <FEncoding `FrameRoman'> <FLocked No> > <String `";
-
-
- // -- Walk over the string, processing superscript directives
- for( unsigned int i = 0; i < shorthand.length(); i++ )
- {
- if( shorthand[i] == '!' )
- {
- // -- Reached logical end of shorthand name
- break;
- }
- else if( shorthand[i] == '^' )
- {
- // -- Process super/subscript formatting
-
- mode_is_normal = !mode_is_normal;
- if( mode_is_normal )
- {
- // -- Back to normal mode
- munged_shorthand += mif_normal;
- }
- else
- {
- // -- Going to superscript mode
- munged_shorthand += mif_superscript;
- }
-
- }
- else if( shorthand[i] == '\\' )
- {
- // -- Process Symbol character set
- if( (i + 1) < shorthand.length() )
- {
- i++; // -- Proceed to next char. Yes I know that changing the loop var is ugly!
- munged_shorthand += mif_symbol;
- munged_shorthand += shorthand[i];
- munged_shorthand += mif_times;
- }
- else
- {
- // -- FIXME: Add line number info later
- cerr << "Encountered a `\\` without anything following it!" << endl;
- exit( -1 );
- }
-
- }
- else
- {
- // -- Pass on un-munged
- munged_shorthand += shorthand[i];
- }
-
- } // -- end for all characters in shorthand
-
- // -- Do any other munging
-
- // -- Return the formatted shorthand name
- return munged_shorthand;
-}
-
-
-// --
-// -- Helper function to figure out where to put rules in the table (kludge before we
-// -- get the tuple attributes into the shorthand machine language.
-// -- Current convention:
-// -- - a `!' in the shorthand indicates the beginning of ruling information
-// -- - `b' => bottom of this row is ruled
-// -- - `r' => right of this column is ruled
-// --
-string formatCellRuling( const string shorthand)
-{
- for( unsigned int i = 0; i < shorthand.length(); i++ )
- {
- if( shorthand[i] == '!' )
- {
- // -- OK, found beginning of ruling information
- for( unsigned int j = i+1; j < shorthand.length(); j++ )
- {
- if( shorthand[j] == 'b')
- {
- // -- Rule the bottom
- return "<CellBRuling `Medium'>\n";
- }
- else if( shorthand[j] == 'r')
- {
- // -- Rule the bottom
- return "<CellRRuling `Medium'>\n";
- }
-
- }
-
- // -- No ruling directives recognized, return default ruling
- return "";
- }
-
- }
-
- // -- No ruling information found, return default ruling
- return "";
-}
diff --git a/src/mem/slicc/generator/mif_gen.hh b/src/mem/slicc/generator/mif_gen.hh
deleted file mode 100644
index 6da75f748..000000000
--- a/src/mem/slicc/generator/mif_gen.hh
+++ /dev/null
@@ -1,45 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id: mif_gen.hh,v 3.1 2001/12/12 01:00:35 milo Exp $
- *
- */
-
-#ifndef MIF_GEN_H
-#define MIF_GEN_H
-
-#include "mem/slicc/symbols/StateMachine.hh"
-
-void printStateTableMIF(const StateMachine& sm, ostream& out);
-void printEventTableMIF(const StateMachine& sm, ostream& out);
-void printActionTableMIF(const StateMachine& sm, ostream& out);
-void printTransitionTableMIF(const StateMachine& sm, ostream& out);
-
-#endif //MIF_GEN_H
diff --git a/src/mem/slicc/main.cc b/src/mem/slicc/main.cc
deleted file mode 100644
index 294925ee1..000000000
--- a/src/mem/slicc/main.cc
+++ /dev/null
@@ -1,246 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- *
- * */
-
-#include "mem/slicc/main.hh"
-#include "mem/slicc/symbols/StateMachine.hh"
-#include "mem/slicc/generator/mif_gen.hh"
-#include "mem/slicc/generator/html_gen.hh"
-#include "mem/slicc/generator/fileio.hh"
-#include "mem/slicc/ast/DeclListAST.hh"
-#include "mem/slicc/symbols/Type.hh"
-#include "mem/slicc/symbols/SymbolTable.hh"
-#include "mem/slicc/symbols/Event.hh"
-#include "mem/slicc/symbols/State.hh"
-#include "mem/slicc/symbols/Action.hh"
-#include "mem/slicc/symbols/Transition.hh"
-
-// -- Main conversion functions
-
-void printDotty(const StateMachine& sm, ostream& out);
-void printTexTable(const StateMachine& sm, ostream& out);
-
-DeclListAST* g_decl_list_ptr;
-DeclListAST* parse(string filename);
-
-int main(int argc, char *argv[])
-{
- cerr << "SLICC v0.3" << endl;
-
- if (argc < 5) {
- cerr << " Usage: generator.exec <code path> <html path> <ident> <html direction> files ... " << endl;
- exit(1);
- }
-
- // The path we should place the generated code
- string code_path(argv[1]);
- code_path += "/";
-
- // The path we should place the generated html
- string html_path(argv[2]);
- html_path += "/";
-
- string ident(argv[3]);
-
- string html_generate(argv[4]);
-
- Vector<DeclListAST*> decl_list_vec;
-
- // Parse
- cerr << "Parsing..." << endl;
- for(int i=5; i<argc; i++) {
- cerr << " " << argv[i] << endl;
- DeclListAST* decl_list_ptr = parse(argv[i]);
- decl_list_vec.insertAtBottom(decl_list_ptr);
- }
-
- // Find machines
- cerr << "Generator pass 1..." << endl;
- int size = decl_list_vec.size();
- for(int i=0; i<size; i++) {
- DeclListAST* decl_list_ptr = decl_list_vec[i];
- decl_list_ptr->findMachines();
- }
-
- // Generate Code
- cerr << "Generator pass 2..." << endl;
- for(int i=0; i<size; i++) {
- DeclListAST* decl_list_ptr = decl_list_vec[i];
- decl_list_ptr->generate();
- delete decl_list_ptr;
- }
-
- // Generate C/C++ files
- cerr << "Writing C files..." << endl;
-
- {
- // Generate the name of the protocol
- ostringstream sstr;
- sstr << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<<endl;
- sstr << endl;
- sstr << "#ifndef PROTOCOL_NAME_H" << endl;
- sstr << "#define PROTOCOL_NAME_H" << endl;
- sstr << endl;
- sstr << "const char CURRENT_PROTOCOL[] = \"";
- sstr << ident << "\";\n";
- sstr << "#endif // PROTOCOL_NAME_H" << endl;
- conditionally_write_file(code_path + "/protocol_name.hh", sstr);
- }
-
- g_sym_table.writeCFiles(code_path);
-
- // Generate HTML files
- if (html_generate == "html") {
- cerr << "Writing HTML files..." << endl;
- g_sym_table.writeHTMLFiles(html_path);
- } else if (html_generate == "no_html") {
- cerr << "No HTML files generated" << endl;
- } else {
- cerr << "ERROR, unidentified html direction" << endl;
- }
-
- cerr << "Done..." << endl;
-
- // Generate MIF files
- cerr << "Writing MIF files..." << endl;
- g_sym_table.writeMIFFiles(html_path);
-
- cerr << "Done..." << endl;
-
-}
- /*
- if(!strcmp(argv[2], "parse")) {
- // Parse only
- } else if(!strcmp(argv[2], "state")) {
- printStateTableMIF(s, cout);
- } else if(!strcmp( argv[2], "event")) {
- printEventTableMIF(s, cout);
- } else if(!strcmp( argv[2], "action")) {
- printActionTableMIF(s, cout);
- } else if(!strcmp( argv[2], "transition")) {
- printTransitionTableMIF(s, cout);
- } else if(!strcmp( argv[2], "tbe")) {
- for(int i=0; i<s.numTypes(); i++) {
- if (s.getType(i).getIdent() == "TBE") {
- printTBETableMIF(s, s.getTypeFields(i), cout);
- }
- }
- } else if(!strcmp( argv[2], "dot")) {
- printDotty(s, cout);
- } else if(!strcmp( argv[2], "latex")) {
- printTexTable(s, cout);
- } else if (!strcmp( argv[2], "murphi")) {
- printMurphi(s, cout);
- } else if (!strcmp( argv[2], "html")) {
- printHTML(s);
- } else if(!strcmp( argv[2], "code")) {
- if (argc < 4) {
- cerr << "Error: Wrong number of command line parameters!" << endl;
- exit(1);
- }
- */
-
-
-void printDotty(const StateMachine& sm, ostream& out)
-{
- out << "digraph " << sm.getIdent() << " {" << endl;
- for(int i=0; i<sm.numTransitions(); i++) {
- const Transition& t = sm.getTransition(i);
- // Don't print ignored transitions
- if ((t.getActionShorthands() != "--") && (t.getActionShorthands() != "z")) {
- // if (t.getStateShorthand() != t.getNextStateShorthand()) {
- out << " " << t.getStateShorthand() << " -> ";
- out << t.getNextStateShorthand() << "[label=\"";
- out << t.getEventShorthand() << "/"
- << t.getActionShorthands() << "\"]" << endl;
- }
- }
- out << "}" << endl;
-}
-
-void printTexTable(const StateMachine& sm, ostream& out)
-{
- const Transition* trans_ptr;
- int stateIndex, eventIndex;
- string actions;
- string nextState;
-
- out << "%& latex" << endl;
- out << "\\documentclass[12pt]{article}" << endl;
- out << "\\usepackage{graphics}" << endl;
- out << "\\begin{document}" << endl;
- // out << "{\\large" << endl;
- out << "\\begin{tabular}{|l||";
- for(eventIndex=0; eventIndex < sm.numEvents(); eventIndex++) {
- out << "l";
- }
- out << "|} \\hline" << endl;
-
- for(eventIndex=0; eventIndex < sm.numEvents(); eventIndex++) {
- out << " & \\rotatebox{90}{";
- out << sm.getEvent(eventIndex).getShorthand();
- out << "}";
- }
- out << "\\\\ \\hline \\hline" << endl;
-
- for(stateIndex=0; stateIndex < sm.numStates(); stateIndex++) {
- out << sm.getState(stateIndex).getShorthand();
- for(eventIndex=0; eventIndex < sm.numEvents(); eventIndex++) {
- out << " & ";
- trans_ptr = sm.getTransPtr(stateIndex, eventIndex);
- if (trans_ptr == NULL) {
- } else {
- actions = trans_ptr->getActionShorthands();
- // FIXME: should compare index, not the string
- if (trans_ptr->getNextStateShorthand() !=
- sm.getState(stateIndex).getShorthand() ) {
- nextState = trans_ptr->getNextStateShorthand();
- } else {
- nextState = "";
- }
-
- out << actions;
- if ((nextState.length() != 0) && (actions.length() != 0)) {
- out << "/";
- }
- out << nextState;
- }
- }
- out << "\\\\" << endl;
- }
- out << "\\hline" << endl;
- out << "\\end{tabular}" << endl;
- // out << "}" << endl;
- out << "\\end{document}" << endl;
-}
-
diff --git a/src/mem/slicc/main.hh b/src/mem/slicc/main.hh
deleted file mode 100644
index a10dcca53..000000000
--- a/src/mem/slicc/main.hh
+++ /dev/null
@@ -1,48 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * main.hh
- *
- * Description:
- *
- * $Id: main.hh,v 3.2 2003/03/17 01:50:01 xu Exp $
- *
- * */
-
-#ifndef MAIN_H
-#define MAIN_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/ast/DeclListAST.hh"
-#include "mem/gems_common/Map.hh"
-
-extern DeclListAST* g_decl_list_ptr;
-
-#endif //MAIN_H
diff --git a/src/mem/slicc/main.py b/src/mem/slicc/main.py
new file mode 100644
index 000000000..f8efcc323
--- /dev/null
+++ b/src/mem/slicc/main.py
@@ -0,0 +1,100 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import os
+import sys
+
+from slicc.parser import SLICC
+
+usage="%prog [options] <files> ... "
+version="%prog v0.4"
+brief_copyright='''
+Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+Copyright (c) 2009 The Hewlett-Packard Development Company
+All Rights Reserved.
+'''
+
+def nprint(format, *args):
+ pass
+
+def eprint(format, *args):
+ if args:
+ format = format % args
+
+ print >>sys.stderr, format
+
+def main(args=None):
+ import optparse
+
+ parser = optparse.OptionParser(usage=usage, version=version,
+ description=brief_copyright)
+ parser.add_option("-d", "--debug", default=False, action="store_true",
+ help="Turn on PLY debugging")
+ parser.add_option("-C", "--code-path", default="generated",
+ help="Path where C++ code output code goes")
+ parser.add_option("-H", "--html-path",
+ help="Path where html output goes")
+ parser.add_option("-F", "--print-files",
+ help="Print files that SLICC will generate")
+ parser.add_option("-q", "--quiet",
+ help="don't print messages")
+ opts,files = parser.parse_args(args=args)
+
+ if len(files) < 1:
+ parser.print_help()
+ sys.exit(2)
+
+ output = nprint if opts.quiet else eprint
+
+ output("SLICC v0.4")
+ slicc = SLICC(debug=opts.debug)
+
+ output("Parsing...")
+ for filename in slicc.load(files, verbose=True):
+ output(" %s", filename)
+
+ if opts.print_files:
+ for i in sorted(slicc.files()):
+ print ' %s' % i
+ else:
+ output("Generator pass 1...")
+ slicc.findMachines()
+
+ output("Generator pass 2...")
+ slicc.generate()
+
+ output("Generating C++ files...")
+ slicc.writeCodeFiles(opts.code_path)
+
+ if opts.html_path:
+ nprint("Writing HTML files...")
+ slicc.writeHTMLFiles(opts.html_path)
+
+ eprint("SLICC is Done.")
+
+if __name__ == "__main__":
+ main()
diff --git a/src/mem/slicc/parser.py b/src/mem/slicc/parser.py
new file mode 100644
index 000000000..6c3f45629
--- /dev/null
+++ b/src/mem/slicc/parser.py
@@ -0,0 +1,667 @@
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Nathan Binkert
+
+import os.path
+import re
+import sys
+
+from m5.util.grammar import Grammar, TokenError, ParseError
+
+import slicc.ast as ast
+import slicc.util as util
+from slicc.symbols import SymbolTable
+
+def read_slicc(sources):
+ if not isinstance(sources, (list,tuple)):
+ sources = [ sources ]
+
+ for source in sources:
+ for sm_file in file(source, "r"):
+ sm_file = sm_file.strip()
+ if not sm_file:
+ continue
+ if sm_file.startswith("#"):
+ continue
+ yield sm_file
+
+class SLICC(Grammar):
+ def __init__(self, **kwargs):
+ super(SLICC, self).__init__(**kwargs)
+ self.decl_list_vec = []
+ self.current_file = None
+ self.symtab = SymbolTable()
+
+ def parse(self, filename):
+ self.current_file = filename
+ f = file(filename, 'r')
+ text = f.read()
+ try:
+ decl_list = super(SLICC, self).parse(text)
+ except (TokenError, ParseError), e:
+ sys.exit("%s: %s:%d" % (e, filename, e.token.lineno))
+ self.decl_list_vec.append(decl_list)
+ self.current_file = None
+
+ def _load(self, *filenames):
+ filenames = list(filenames)
+ while filenames:
+ f = filenames.pop(0)
+ if isinstance(f, (list, tuple)):
+ filenames[0:0] = list(f)
+ continue
+
+ yield f
+ if f.endswith(".slicc"):
+ dirname,basename = os.path.split(f)
+ filenames[0:0] = [ os.path.join(dirname, x) \
+ for x in read_slicc(f)]
+ else:
+ assert f.endswith(".sm")
+ self.parse(f)
+
+ def load(self, *filenames, **kwargs):
+ verbose = kwargs.pop("verbose", False)
+ if kwargs:
+ raise TypeError
+
+ gen = self._load(*filenames)
+ if verbose:
+ return gen
+ else:
+ # Run out the generator if we don't want the verbosity
+ for foo in gen:
+ pass
+
+ def findMachines(self):
+ for decl_list in self.decl_list_vec:
+ decl_list.findMachines()
+
+ def generate(self):
+ for decl_list in self.decl_list_vec:
+ decl_list.generate()
+
+ def writeCodeFiles(self, code_path):
+ util.makeDir(code_path)
+ self.symtab.writeCodeFiles(code_path)
+
+ def writeHTMLFiles(self, code_path):
+ util.makeDir(code_path)
+ self.symtab.writeHTMLFiles(code_path)
+
+ def files(self):
+ f = set([
+ 'ControllerFactory.cc',
+ 'ControllerFactory.hh',
+ 'MachineType.cc',
+ 'MachineType.hh',
+ 'Types.hh' ])
+
+ for decl_list in self.decl_list_vec:
+ f |= decl_list.files()
+
+ return f
+
+ t_ignore = '\t '
+
+ # C or C++ comment (ignore)
+ def t_c_comment(self, t):
+ r'/\*(.|\n)*?\*/'
+ t.lexer.lineno += t.value.count('\n')
+
+ def t_cpp_comment(self, t):
+ r'//.*'
+
+ # Define a rule so we can track line numbers
+ def t_newline(self, t):
+ r'\n+'
+ t.lexer.lineno += len(t.value)
+
+ reserved = {
+ 'global' : 'GLOBAL',
+ 'machine' : 'MACHINE',
+ 'in_port' : 'IN_PORT',
+ 'out_port' : 'OUT_PORT',
+ 'action' : 'ACTION',
+ 'transition' : 'TRANS',
+ 'structure' : 'STRUCT',
+ 'external_type' : 'EXTERN_TYPE',
+ 'enumeration' : 'ENUM',
+ 'peek' : 'PEEK',
+ 'enqueue' : 'ENQUEUE',
+ 'copy_head' : 'COPY_HEAD',
+ 'check_allocate' : 'CHECK_ALLOCATE',
+ 'check_stop_slots' : 'CHECK_STOP_SLOTS',
+ 'if' : 'IF',
+ 'else' : 'ELSE',
+ 'return' : 'RETURN',
+ 'THIS' : 'THIS',
+ 'CHIP' : 'CHIP',
+ 'void' : 'VOID',
+ 'new' : 'NEW',
+ }
+
+ literals = ':[]{}(),='
+
+ tokens = [ 'EQ', 'NE', 'LT', 'GT', 'LE', 'GE',
+ 'LEFTSHIFT', 'RIGHTSHIFT',
+ 'NOT', 'AND', 'OR',
+ 'PLUS', 'DASH', 'STAR', 'SLASH',
+ 'DOUBLE_COLON', 'SEMI',
+ 'ASSIGN', 'DOT',
+ 'IDENT', 'LIT_BOOL', 'FLOATNUMBER', 'NUMBER', 'STRING' ]
+ tokens += reserved.values()
+
+ t_EQ = r'=='
+ t_NE = r'!='
+ t_LT = r'<'
+ t_GT = r'>'
+ t_LE = r'<='
+ t_GE = r'>='
+ t_LEFTSHIFT = r'<<'
+ t_RIGHTSHIFT = r'>>'
+ t_NOT = r'!'
+ t_AND = r'&&'
+ t_OR = r'\|\|'
+ t_PLUS = r'\+'
+ t_DASH = r'-'
+ t_STAR = r'\*'
+ t_SLASH = r'/'
+ t_DOUBLE_COLON = r'::'
+ t_SEMI = r';'
+ t_ASSIGN = r':='
+ t_DOT = r'\.'
+
+ precedence = (
+ ('left', 'AND', 'OR'),
+ ('left', 'EQ', 'NE'),
+ ('left', 'LT', 'GT', 'LE', 'GE'),
+ ('left', 'RIGHTSHIFT', 'LEFTSHIFT'),
+ ('left', 'PLUS', 'DASH'),
+ ('left', 'STAR', 'SLASH'),
+ ('right', 'NOT', 'UMINUS'),
+ )
+
+ def t_IDENT(self, t):
+ r'[a-zA-Z_][a-zA-Z_0-9]*'
+ if t.value == 'true':
+ t.type = 'LIT_BOOL'
+ t.value = True
+ return t
+
+ if t.value == 'false':
+ t.type = 'LIT_BOOL'
+ t.value = False
+ return t
+
+ # Check for reserved words
+ t.type = self.reserved.get(t.value, 'IDENT')
+ return t
+
+ def t_FLOATNUMBER(self, t):
+ '[0-9]+[.][0-9]+'
+ try:
+ t.value = float(t.value)
+ except ValueError:
+ raise TokenError("Illegal float", t)
+ return t
+
+ def t_NUMBER(self, t):
+ r'[0-9]+'
+ try:
+ t.value = int(t.value)
+ except ValueError:
+ raise TokenError("Illegal number", t)
+ return t
+
+ def t_STRING1(self, t):
+ r'\"[^"\n]*\"'
+ t.type = 'STRING'
+ t.value = t.value[1:-1]
+ return t
+
+ def t_STRING2(self, t):
+ r"\'[^'\n]*\'"
+ t.type = 'STRING'
+ t.value = t.value[1:-1]
+ return t
+
+ def p_file(self, p):
+ "file : decls"
+ p[0] = p[1]
+
+ def p_empty(self, p):
+ "empty :"
+
+ def p_decls(self, p):
+ "decls : declsx"
+ p[0] = ast.DeclListAST(self, p[1])
+
+ def p_declsx__list(self, p):
+ "declsx : decl declsx"
+ p[0] = [ p[1] ] + p[2]
+
+ def p_declsx__none(self, p):
+ "declsx : empty"
+ p[0] = []
+
+ def p_decl__machine(self, p):
+ "decl : MACHINE '(' ident pairs ')' ':' params '{' decls '}'"
+ p[0] = ast.MachineAST(self, p[3], p[4], p[7], p[9])
+
+ def p_decl__action(self, p):
+ "decl : ACTION '(' ident pairs ')' statements"
+ p[0] = ast.ActionDeclAST(self, p[3], p[4], p[6])
+
+ def p_decl__in_port(self, p):
+ "decl : IN_PORT '(' ident ',' type ',' var pairs ')' statements"
+ p[0] = ast.InPortDeclAST(self, p[3], p[5], p[7], p[8], p[10])
+
+ def p_decl__out_port(self, p):
+ "decl : OUT_PORT '(' ident ',' type ',' var pairs ')' SEMI"
+ p[0] = ast.OutPortDeclAST(self, p[3], p[5], p[7], p[8])
+
+ def p_decl__trans0(self, p):
+ "decl : TRANS '(' idents ',' idents ',' ident pairs ')' idents"
+ p[0] = ast.TransitionDeclAST(self, p[3], p[5], p[7], p[8], p[10])
+
+ def p_decl__trans1(self, p):
+ "decl : TRANS '(' idents ',' idents pairs ')' idents"
+ p[0] = ast.TransitionDeclAST(self, p[3], p[5], None, p[6], p[8])
+
+ def p_decl__extern0(self, p):
+ "decl : EXTERN_TYPE '(' type pairs ')' SEMI"
+ p[4]["external"] = "yes"
+ p[0] = ast.TypeDeclAST(self, p[3], p[4], [])
+
+ def p_decl__extern1(self, p):
+ "decl : EXTERN_TYPE '(' type pairs ')' '{' type_methods '}'"
+ p[4]["external"] = "yes"
+ p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7])
+
+ def p_decl__global(self, p):
+ "decl : GLOBAL '(' type pairs ')' '{' type_members '}'"
+ p[4]["global"] = "yes"
+ p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7])
+
+ def p_decl__struct(self, p):
+ "decl : STRUCT '(' type pairs ')' '{' type_members '}'"
+ p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7])
+
+ def p_decl__enum(self, p):
+ "decl : ENUM '(' type pairs ')' '{' type_enums '}'"
+ p[4]["enumeration"] = "yes"
+ p[0] = ast.EnumDeclAST(self, p[3], p[4], p[7])
+
+ def p_decl__object(self, p):
+ "decl : type ident pairs SEMI"
+ p[0] = ast.ObjDeclAST(self, p[1], p[2], p[3])
+
+ def p_decl__func_decl(self, p):
+ """decl : void ident '(' params ')' pairs SEMI
+ | type ident '(' params ')' pairs SEMI"""
+ p[0] = ast.FuncDeclAST(self, p[1], p[2], p[4], p[6], None)
+
+ def p_decl__func_def(self, p):
+ """decl : void ident '(' params ')' pairs statements
+ | type ident '(' params ')' pairs statements"""
+ p[0] = ast.FuncDeclAST(self, p[1], p[2], p[4], p[6], p[7])
+
+ # Type fields
+ def p_type_members__list(self, p):
+ "type_members : type_member type_members"
+ p[0] = [ p[1] ] + p[2]
+
+ def p_type_members__empty(self, p):
+ "type_members : empty"
+ p[0] = []
+
+ def p_type_member__1(self, p):
+ "type_member : type ident pairs SEMI"
+ p[0] = ast.TypeFieldMemberAST(self, p[1], p[2], p[3], None)
+
+ def p_type_member__2(self, p):
+ "type_member : type ident ASSIGN expr SEMI"
+ p[0] = ast.TypeFieldMemberAST(self, p[1], p[2],
+ ast.PairListAST(self), p[4])
+
+ # Methods
+ def p_type_methods__list(self, p):
+ "type_methods : type_method type_methods"
+ p[0] = [ p[1] ] + p[2]
+
+ def p_type_methods(self, p):
+ "type_methods : empty"
+ p[0] = []
+
+ def p_type_method(self, p):
+ "type_method : type_or_void ident '(' types ')' pairs SEMI"
+ p[0] = ast.TypeFieldMethodAST(self, p[1], p[2], p[4], p[6])
+
+ # Enum fields
+ def p_type_enums__list(self, p):
+ "type_enums : type_enum type_enums"
+ p[0] = [ p[1] ] + p[2]
+
+ def p_type_enums__empty(self, p):
+ "type_enums : empty"
+ p[0] = []
+
+ def p_type_enum(self, p):
+ "type_enum : ident pairs SEMI"
+ p[0] = ast.TypeFieldEnumAST(self, p[1], p[2])
+
+ # Type
+ def p_types__multiple(self, p):
+ "types : type ',' types"
+ p[0] = [ p[1] ] + p[3]
+
+ def p_types__one(self, p):
+ "types : type"
+ p[0] = [ p[1] ]
+
+ def p_types__empty(self, p):
+ "types : empty"
+ p[0] = []
+
+ def p_type(self, p):
+ "type : ident"
+ p[0] = ast.TypeAST(self, p[1])
+
+ def p_void(self, p):
+ "void : VOID"
+ p[0] = ast.TypeAST(self, p[1])
+
+ def p_type_or_void(self, p):
+ """type_or_void : type
+ | void"""
+ p[0] = p[1]
+
+ # Formal Param
+ def p_params__many(self, p):
+ "params : param ',' params"
+ p[0] = [ p[1] ] + p[3]
+
+ def p_params__one(self, p):
+ "params : param"
+ p[0] = [ p[1] ]
+
+ def p_params__none(self, p):
+ "params : empty"
+ p[0] = []
+
+ def p_param(self, p):
+ "param : type ident"
+ p[0] = ast.FormalParamAST(self, p[1], p[2])
+
+ # Idents and lists
+ def p_idents__braced(self, p):
+ "idents : '{' identx '}'"
+ p[0] = p[2]
+
+ def p_idents__bare(self, p):
+ "idents : ident"
+ p[0] = [ p[1] ]
+
+ def p_identx__multiple_1(self, p):
+ """identx : ident SEMI identx
+ | ident ',' identx"""
+ p[0] = [ p[1] ] + p[3]
+
+ def p_identx__multiple_2(self, p):
+ "identx : ident identx"
+ p[0] = [ p[1] ] + p[2]
+
+ def p_identx__single(self, p):
+ "identx : empty"
+ p[0] = [ ]
+
+ def p_ident(self, p):
+ "ident : IDENT"
+ p[0] = p[1]
+
+ # Pair and pair lists
+ def p_pairs__list(self, p):
+ "pairs : ',' pairsx"
+ p[0] = p[2]
+
+ def p_pairs__empty(self, p):
+ "pairs : empty"
+ p[0] = ast.PairListAST(self)
+
+ def p_pairsx__many(self, p):
+ "pairsx : pair ',' pairsx"
+ p[0] = p[3]
+ p[0].addPair(p[1])
+
+ def p_pairsx__one(self, p):
+ "pairsx : pair"
+ p[0] = ast.PairListAST(self)
+ p[0].addPair(p[1])
+
+ def p_pair__assign(self, p):
+ """pair : ident '=' STRING
+ | ident '=' ident"""
+ p[0] = ast.PairAST(self, p[1], p[3])
+
+ def p_pair__literal(self, p):
+ "pair : STRING"
+ p[0] = ast.PairAST(self, "short", p[1])
+
+ # Below are the rules for action descriptions
+ def p_statements__inner(self, p):
+ "statements : '{' statements_inner '}'"
+ p[0] = ast.StatementListAST(self, p[2])
+
+ def p_statements__none(self, p):
+ "statements : '{' '}'"
+ p[0] = ast.StatementListAST(self, [])
+
+ def p_statements_inner__many(self, p):
+ "statements_inner : statement statements_inner"
+ p[0] = [ p[1] ] + p[2]
+
+ def p_statements_inner__one(self, p):
+ "statements_inner : statement"
+ p[0] = [ p[1] ]
+
+ def p_exprs__multiple(self, p):
+ "exprs : expr ',' exprs"
+ p[0] = [ p[1] ] + p[3]
+
+ def p_exprs__one(self, p):
+ "exprs : expr"
+ p[0] = [ p[1] ]
+
+ def p_exprs__empty(self, p):
+ "exprs : empty"""
+ p[0] = []
+
+ def p_statement__expression(self, p):
+ "statement : expr SEMI"
+ p[0] = ast.ExprStatementAST(self, p[1])
+
+ def p_statement__assign(self, p):
+ "statement : expr ASSIGN expr SEMI"
+ p[0] = ast.AssignStatementAST(self, p[1], p[3])
+
+ def p_statement__enqueue(self, p):
+ "statement : ENQUEUE '(' var ',' type pairs ')' statements"
+ p[0] = ast.EnqueueStatementAST(self, p[3], p[5], p[6], p[8])
+
+ def p_statement__peek(self, p):
+ "statement : PEEK '(' var ',' type ')' statements"
+ p[0] = ast.PeekStatementAST(self, p[3], p[5], p[7], "peek")
+
+ def p_statement__copy_head(self, p):
+ "statement : COPY_HEAD '(' var ',' var pairs ')' SEMI"
+ p[0] = ast.CopyHeadStatementAST(self, p[3], p[5], p[6])
+
+ def p_statement__check_allocate(self, p):
+ "statement : CHECK_ALLOCATE '(' var ')' SEMI"
+ p[0] = ast.CheckAllocateStatementAST(self, p[3])
+
+ def p_statement__check_stop(self, p):
+ "statement : CHECK_STOP_SLOTS '(' var ',' STRING ',' STRING ')' SEMI"
+ p[0] = ast.CheckStopStatementAST(self, p[3], p[5], p[7])
+
+ def p_statement__return(self, p):
+ "statement : RETURN expr SEMI"
+ p[0] = ast.ReturnStatementAST(self, p[2])
+
+ def p_statement__if(self, p):
+ "statement : if_statement"
+ p[0] = p[1]
+
+ def p_if_statement__if(self, p):
+ "if_statement : IF '(' expr ')' statements"
+ p[0] = ast.IfStatementAST(self, p[3], p[5], None)
+
+ def p_if_statement__if_else(self, p):
+ "if_statement : IF '(' expr ')' statements ELSE statements"
+ p[0] = ast.IfStatementAST(self, p[3], p[5], p[7])
+
+ def p_statement__if_else_if(self, p):
+ "if_statement : IF '(' expr ')' statements ELSE if_statement"
+ p[0] = ast.IfStatementAST(self, p[3], p[5],
+ ast.StatementListAST(self, p[7]))
+
+ def p_expr__var(self, p):
+ "aexpr : var"
+ p[0] = p[1]
+
+ def p_expr__literal(self, p):
+ "aexpr : literal"
+ p[0] = p[1]
+
+ def p_expr__enumeration(self, p):
+ "aexpr : enumeration"
+ p[0] = p[1]
+
+ def p_expr__func_call(self, p):
+ "aexpr : ident '(' exprs ')'"
+ p[0] = ast.FuncCallExprAST(self, p[1], p[3])
+
+ def p_expr__new(self, p):
+ "aexpr : NEW type"
+ p[0] = ast.NewExprAST(self, p[2])
+
+ # globally access a local chip component and call a method
+ def p_expr__local_chip_method(self, p):
+ "aexpr : THIS DOT var '[' expr ']' DOT var DOT ident '(' exprs ')'"
+ p[0] = ast.LocalChipMethodAST(self, p[3], p[5], p[8], p[10], p[12])
+
+ # globally access a local chip component and access a data member
+ def p_expr__local_chip_member(self, p):
+ "aexpr : THIS DOT var '[' expr ']' DOT var DOT field"
+ p[0] = ast.LocalChipMemberAST(self, p[3], p[5], p[8], p[10])
+
+ # globally access a specified chip component and call a method
+ def p_expr__specified_chip_method(self, p):
+ "aexpr : CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT ident '(' exprs ')'"
+ p[0] = ast.SpecifiedChipMethodAST(self, p[3], p[6], p[8], p[11], p[13],
+ p[15])
+
+ # globally access a specified chip component and access a data member
+ def p_expr__specified_chip_member(self, p):
+ "aexpr : CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT field"
+ p[0] = ast.SpecifiedChipMemberAST(self, p[3], p[6], p[8], p[11], p[13])
+
+ def p_expr__member(self, p):
+ "aexpr : aexpr DOT ident"
+ p[0] = ast.MemberExprAST(self, p[1], p[3])
+
+ def p_expr__member_method_call(self, p):
+ "aexpr : aexpr DOT ident '(' exprs ')'"
+ p[0] = ast.MemberMethodCallExprAST(self, p[1], p[3], p[5])
+
+ def p_expr__member_method_call_lookup(self, p):
+ "aexpr : aexpr '[' exprs ']'"
+ p[0] = ast.MemberMethodCallExprAST(self, p[1], "lookup", p[3])
+
+ def p_expr__class_method_call(self, p):
+ "aexpr : type DOUBLE_COLON ident '(' exprs ')'"
+ p[0] = ast.ClassMethodCallExprAST(self, p[1], p[3], p[5])
+
+ def p_expr__aexpr(self, p):
+ "expr : aexpr"
+ p[0] = p[1]
+
+ def p_expr__binary_op(self, p):
+ """expr : expr STAR expr
+ | expr SLASH expr
+ | expr PLUS expr
+ | expr DASH expr
+ | expr LT expr
+ | expr GT expr
+ | expr LE expr
+ | expr GE expr
+ | expr EQ expr
+ | expr NE expr
+ | expr AND expr
+ | expr OR expr
+ | expr RIGHTSHIFT expr
+ | expr LEFTSHIFT expr"""
+ p[0] = ast.InfixOperatorExprAST(self, p[1], p[2], p[3])
+
+ # FIXME - unary not
+ def p_expr__unary_op(self, p):
+ """expr : NOT expr
+ | DASH expr %prec UMINUS"""
+ p[0] = PrefixOperatorExpr(p[1], p[2])
+
+ def p_expr__parens(self, p):
+ "aexpr : '(' expr ')'"
+ p[0] = p[2]
+
+ def p_literal__string(self, p):
+ "literal : STRING"
+ p[0] = ast.LiteralExprAST(self, p[1], "string")
+
+ def p_literal__number(self, p):
+ "literal : NUMBER"
+ p[0] = ast.LiteralExprAST(self, p[1], "int")
+
+ def p_literal__float(self, p):
+ "literal : FLOATNUMBER"
+ p[0] = ast.LiteralExprAST(self, p[1], "int")
+
+ def p_literal__bool(self, p):
+ "literal : LIT_BOOL"
+ p[0] = ast.LiteralExprAST(self, p[1], "bool")
+
+ def p_enumeration(self, p):
+ "enumeration : ident ':' ident"
+ p[0] = ast.EnumExprAST(self, ast.TypeAST(self, p[1]), p[3])
+
+ def p_var(self, p):
+ "var : ident"
+ p[0] = ast.VarExprAST(self, p[1])
+
+ def p_field(self, p):
+ "field : ident"
+ p[0] = p[1]
diff --git a/src/mem/slicc/parser/lexer.ll b/src/mem/slicc/parser/lexer.ll
deleted file mode 100644
index b2d36855b..000000000
--- a/src/mem/slicc/parser/lexer.ll
+++ /dev/null
@@ -1,125 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- */
-
-%{
-
-#include <assert.h>
-#include "mem/slicc/ast/ASTs.hh"
-#include "parser.hh"
-#include <string>
-
-extern "C" int yylex();
-extern "C" void yyerror();
-extern "C" int yywrap()
-{
- return 1;
-}
-
-%}
-%x CMNT
-%x IMBEDED
-%%
-
-[\t ]+ /* Ignore whitespace */
-[\n] { g_line_number++; }
-"//".*[\n] { g_line_number++; } /* C++ style comments */
-
-"/*" BEGIN CMNT;
-<CMNT>. ;
-<CMNT>\n { g_line_number++; }
-<CMNT>"*/" { BEGIN INITIAL; }
-
-true { yylval.str_ptr = new string(yytext); return LIT_BOOL; }
-false { yylval.str_ptr = new string(yytext); return LIT_BOOL; }
-global { return GLOBAL_DECL; }
-machine { return MACHINE_DECL; }
-in_port { return IN_PORT_DECL; }
-out_port { return OUT_PORT_DECL; }
-action { return ACTION_DECL; }
-transition { return TRANSITION_DECL; }
-structure { return STRUCT_DECL; }
-external_type { return EXTERN_TYPE_DECL; }
-enumeration { return ENUM_DECL; }
-peek { return PEEK; }
-enqueue { return ENQUEUE; }
-copy_head { return COPY_HEAD; }
-check_allocate { return CHECK_ALLOCATE; }
-check_stop_slots { return CHECK_STOP_SLOTS; }
-if { return IF; }
-else { return ELSE; }
-return { return RETURN; }
-THIS { return THIS; }
-CHIP { return CHIP; }
-void { yylval.str_ptr = new string(yytext); return VOID; }
-new { return NEW; }
-
-== { yylval.str_ptr = new string(yytext); return EQ; }
-!= { yylval.str_ptr = new string(yytext); return NE; }
-[<] { yylval.str_ptr = new string(yytext); return '<'; }
-[>] { yylval.str_ptr = new string(yytext); return '>'; }
-[<][<] { yylval.str_ptr = new string(yytext); return LEFTSHIFT; }
-[>][>] { yylval.str_ptr = new string(yytext); return RIGHTSHIFT; }
-[<][=] { yylval.str_ptr = new string(yytext); return LE; }
-[>][=] { yylval.str_ptr = new string(yytext); return GE; }
-[!] { yylval.str_ptr = new string(yytext); return NOT; }
-[&][&] { yylval.str_ptr = new string(yytext); return AND; }
-[|][|] { yylval.str_ptr = new string(yytext); return OR; }
-[+] { yylval.str_ptr = new string(yytext); return PLUS; }
-[-] { yylval.str_ptr = new string(yytext); return DASH; }
-[*] { yylval.str_ptr = new string(yytext); return STAR; }
-[/] { yylval.str_ptr = new string(yytext); return SLASH; }
-:: { return DOUBLE_COLON; }
-[:] { return ':'; }
-[;] { return SEMICOLON; }
-[[] { return '['; }
-[]] { return ']'; }
-[{] { return '{'; }
-[}] { return '}'; }
-[(] { return '('; }
-[)] { return ')'; }
-[,] { return ','; }
-[=] { return '='; }
-:= { return ASSIGN; }
-[.] { return DOT; }
-
-[0-9]*[.][0-9]* { yylval.str_ptr = new string(yytext); return FLOATNUMBER; }
-[0-9]* { yylval.str_ptr = new string(yytext); return NUMBER; }
-
-[a-zA-Z_][a-zA-Z_0-9]{0,50} { yylval.str_ptr = new string(yytext); return IDENT; }
-\"[^"\n]*\" { yytext[strlen(yytext)-1] = '\0'; yylval.str_ptr = new string(yytext+1); return STRING; }
-\'[^'\n]*\' { yytext[strlen(yytext)-1] = '\0'; yylval.str_ptr = new string(yytext+1); return STRING; }
-
-. { return OTHER; } /* Need so that we handle all characters */
-
-%%
-
diff --git a/src/mem/slicc/parser/parser.py b/src/mem/slicc/parser/parser.py
deleted file mode 100644
index 7fecfd273..000000000
--- a/src/mem/slicc/parser/parser.py
+++ /dev/null
@@ -1,563 +0,0 @@
-# Copyright (c) 2009 The Hewlett-Packard Development Company
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met: redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer;
-# redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution;
-# neither the name of the copyright holders nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# Authors: Nathan Binkert
-
-from ply import lex, yacc
-import re
-
-t_ignore = '\t '
-
-# C or C++ comment (ignore)
-def t_c_comment(t):
- r'/\*(.|\n)*?\*/'
- t.lexer.lineno += t.value.count('\n')
-
-def t_cpp_comment(t):
- r'//.*'
- pass
-
-# Define a rule so we can track line numbers
-def t_newline(t):
- r'\n+'
- t.lexer.lineno += len(t.value)
-
-reserved = {
- 'global' : 'GLOBAL',
- 'machine' : 'MACHINE',
- 'in_port' : 'IN_PORT',
- 'out_port' : 'OUT_PORT',
- 'action' : 'ACTION',
- 'transition' : 'TRANS',
- 'structure' : 'STRUCT',
- 'external_type' : 'EXTERN_TYPE',
- 'enumeration' : 'ENUM',
- 'peek' : 'PEEK',
- 'enqueue' : 'ENQUEUE',
- 'copy_head' : 'COPY_HEAD',
- 'check_allocate' : 'CHECK_ALLOCATE',
- 'check_stop_slots' : 'CHECK_STOP_SLOTS',
- 'if' : 'IF',
- 'else' : 'ELSE',
- 'return' : 'RETURN',
- 'THIS' : 'THIS',
- 'CHIP' : 'CHIP',
- 'void' : 'VOID',
- 'new' : 'NEW',
-}
-
-literals = ':[]{}(),='
-
-tokens = [ 'EQ', 'NE', 'LT', 'GT', 'LE', 'GE',
- 'LEFTSHIFT', 'RIGHTSHIFT',
- 'NOT', 'AND', 'OR',
- 'PLUS', 'DASH', 'STAR', 'SLASH',
- 'DOUBLE_COLON', 'SEMICOLON',
- 'ASSIGN', 'DOT',
- 'IDENT', 'LIT_BOOL', 'FLOATNUMBER', 'NUMBER', 'STRING' ]
-tokens += reserved.values()
-
-t_EQ = r'=='
-t_NE = r'!='
-t_LT = r'<'
-t_GT = r'>'
-t_LE = r'<='
-t_GE = r'>='
-t_LEFTSHIFT = r'<<'
-t_RIGHTSHIFT = r'>>'
-t_NOT = r'!'
-t_AND = r'&&'
-t_OR = r'\|\|'
-t_PLUS = r'\+'
-t_DASH = r'-'
-t_STAR = r'\*'
-t_SLASH = r'/'
-t_DOUBLE_COLON = r'::'
-t_SEMICOLON = r';'
-t_ASSIGN = r':='
-t_DOT = r'\.'
-
-class TokenError(Exception):
- def __init__(self, msg, t):
- super(TokenError, self).__init__(msg)
- self.token = t
-
-class ParseError(Exception):
- def __init__(self, msg, t):
- super(ParseError, self).__init__(msg)
- self.token = t
-
-def t_error(t):
- raise TokenError("Illegal character", t)
-
-def t_IDENT(t):
- r'[a-zA-Z_][a-zA-Z_0-9]*'
- if t.value == 'true':
- t.type = 'LIT_BOOL'
- t.value = True
- return t
-
- if t.value == 'false':
- t.type = 'LIT_BOOL'
- t.value = False
- return t
-
- if t.value.startswith('LATENCY_'):
- t.type = 'LATENCY'
- return t
-
- t.type = reserved.get(t.value, 'IDENT') # Check for reserved words
- return t
-
-def t_FLOATNUMBER(t):
- '[0-9]+[.][0-9]+'
- try:
- t.value = float(t.value)
- except ValueError:
- raise TokenError("Illegal float", t)
- return t
-
-def t_NUMBER(t):
- r'[0-9]+'
- try:
- t.value = int(t.value)
- except ValueError:
- raise TokenError("Illegal number", t)
- return t
-
-def t_STRING1(t):
- r'\"[^"\n]*\"'
- t.type = 'STRING'
- return t
-
-def t_STRING2(t):
- r"\'[^'\n]*\'"
- t.type = 'STRING'
- return t
-
-
-def p_file(p):
- "file : decl_l"
- p[0] = [ x for x in p[1] if x is not None ]
-
-def p_error(t):
- raise ParseError("Syntax error", t)
-
-def p_empty(p):
- "empty :"
- pass
-
-def p_decl_l(p):
- "decl_l : decls"
- p[0] = p[1]
-
-def p_decls(p):
- """decls : decl decls
- | empty"""
- if len(p) == 3:
- p[0] = [ p[1] ] + p[2]
- elif len(p) == 2:
- p[0] = []
-
-def p_decl(p):
- """decl : d_machine
- | d_action
- | d_in_port
- | d_out_port
- | t_trans
- | d_extern
- | d_global
- | d_struct
- | d_enum
- | d_object
- | d_func_decl
- | d_func_def"""
- p[0] = p[1]
-
-def p_d_machine(p):
- """d_machine : MACHINE '(' ident pair_l ')' ':' param_l '{' decl_l '}'"""
-
- if len(p) == 9:
- decl_l = p[7]
- elif len(p) == 11:
- decl_l = p[9]
- decls = [ x for x in decl_l if x is not None ]
- p[0] = Machine(p[3], decls)
-
-def p_d_action(p):
- "d_action : ACTION '(' ident pair_l ')' statement_l"
- p[0] = Action(p[3])
-
-def p_d_in_port(p):
- "d_in_port : IN_PORT '(' ident ',' type ',' var pair_l ')' statement_l"
- p[0] = InPort(p[3])
-
-def p_d_out_port(p):
- "d_out_port : OUT_PORT '(' ident ',' type ',' var pair_l ')' SEMICOLON"
- p[0] = OutPort(p[3])
-
-def p_t_trans(p):
- """t_trans : TRANS '(' ident_l ',' ident_l ',' ident pair_l ')' ident_l
- | TRANS '(' ident_l ',' ident_l pair_l ')' ident_l"""
- p[0] = Transition("transition")
-
-def p_d_extern(p):
- """d_extern : EXTERN_TYPE '(' type pair_l ')' SEMICOLON
- | EXTERN_TYPE '(' type pair_l ')' '{' type_methods '}'"""
- p[0] = Extern(p[3])
-
-def p_d_global(p):
- "d_global : GLOBAL '(' type pair_l ')' '{' type_members '}'"
- p[0] = Global(p[3])
-
-def p_d_struct(p):
- "d_struct : STRUCT '(' type pair_l ')' '{' type_members '}'"
- p[0] = Struct(p[3])
-
-def p_d_enum(p):
- "d_enum : ENUM '(' type pair_l ')' '{' type_enums '}'"
- p[0] = Enum(p[3])
-
-def p_d_object(p):
- "d_object : type ident pair_l SEMICOLON"
- p[0] = Object(p[2])
-
-def p_d_func_decl(p):
- """d_func_decl : void ident '(' param_l ')' pair_l SEMICOLON
- | type ident '(' param_l ')' pair_l SEMICOLON"""
- pass
-
-def p_d_func_def(p):
- """d_func_def : void ident '(' param_l ')' pair_l statement_l
- | type ident '(' param_l ')' pair_l statement_l"""
- p[0] = Function(p[2])
-
-# Type fields
-def p_type_members(p):
- """type_members : type_member type_members
- | empty"""
- pass
-
-def p_type_member(p):
- """type_member : type ident pair_l SEMICOLON
- | type ident ASSIGN expr SEMICOLON"""
- pass
-
-# Methods
-def p_type_methods(p):
- """type_methods : type_method type_methods
- | empty"""
- pass
-
-def p_type_method(p):
- "type_method : type_or_void ident '(' type_l ')' pair_l SEMICOLON"
- pass
-
-# Enum fields
-def p_type_enums(p):
- """type_enums : type_enum type_enums
- | empty"""
- pass
-
-def p_type_enum(p):
- "type_enum : ident pair_l SEMICOLON"
- pass
-
-# Type
-def p_type_l(p):
- """type_l : types
- | empty"""
- pass
-
-def p_types(p):
- """types : type ',' types
- | type"""
- pass
-
-def p_type(p):
- "type : ident"
- p[0] = p[1]
-
-def p_void(p):
- "void : VOID"
- p[0] = None
-
-def p_type_or_void(p):
- """type_or_void : type
- | void"""
- p[0] = p[1]
-
-# Formal Param
-def p_param_l(p):
- """param_l : params
- | empty"""
- pass
-
-def p_params(p):
- """params : param ',' params
- | param"""
- pass
-
-def p_param(p):
- "param : type ident"
- pass
-
-# Idents and lists
-def p_ident(p):
- "ident : IDENT"
- p[0] = p[1]
-
-def p_ident_l(p):
- """ident_l : '{' idents '}'
- | ident"""
- p[0] = p[1]
-
-def p_idents(p):
- """idents : ident SEMICOLON idents
- | ident ',' idents
- | ident idents
- | empty"""
- pass
-
-# Pair and pair lists
-def p_pair_l(p):
- """pair_l : ',' pairs
- | empty"""
- if len(p) == 3:
- p[0] = p[2]
- elif len(p) == 2:
- p[0] = None
-
-def p_pairs(p):
- """pairs : pair ',' pairs
- | pair"""
- if len(p) == 4:
- p[3].append(p[1])
- p[0] = p[3]
- elif len(p) == 2:
- p[0] = [ p[1] ]
-
-def p_pair(p):
- """pair : ident '=' STRING
- | ident '=' ident
- | STRING"""
- if len(p) == 4:
- p[0] = p[1], p[3]
- elif len(p) == 2:
- p[0] = "short", p[1]
-
-# Below are the rules for action descriptions
-def p_statement_l(p):
- "statement_l : '{' statements '}'"
- pass
-
-def p_statements(p):
- """statements : statement statements
- | empty"""
- pass
-
-def p_expr_l(p):
- """expr_l : expr ',' expr_l
- | expr
- | empty"""
- pass
-
-def p_statement(p):
- """statement : expr SEMICOLON
- | expr ASSIGN expr SEMICOLON
- | ENQUEUE '(' var ',' type pair_l ')' statement_l
- | PEEK '(' var ',' type ')' statement_l
- | COPY_HEAD '(' var ',' var pair_l ')' SEMICOLON
- | CHECK_ALLOCATE '(' var ')' SEMICOLON
- | CHECK_STOP_SLOTS '(' var ',' STRING ',' STRING ')' SEMICOLON
- | if_statement
- | RETURN expr SEMICOLON"""
- pass
-
-def p_if_statement(p):
- """if_statement : IF '(' expr ')' statement_l ELSE statement_l
- | IF '(' expr ')' statement_l
- | IF '(' expr ')' statement_l ELSE if_statement"""
- pass
-
-def p_expr(p):
- """expr : var
- | literal
- | enumeration
- | ident '(' expr_l ')'
- | NEW type
- | THIS DOT var '[' expr ']' DOT var DOT ident '(' expr_l ')'
- | THIS DOT var '[' expr ']' DOT var DOT ident
- | CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT ident '(' expr_l ')'
- | CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT ident
- | expr DOT ident
- | expr DOT ident '(' expr_l ')'
- | type DOUBLE_COLON ident '(' expr_l ')'
- | expr '[' expr_l ']'
- | expr STAR expr
- | expr SLASH expr
- | expr PLUS expr
- | expr DASH expr
- | expr LT expr
- | expr GT expr
- | expr LE expr
- | expr GE expr
- | expr EQ expr
- | expr NE expr
- | expr AND expr
- | expr OR expr
- | NOT expr
- | expr RIGHTSHIFT expr
- | expr LEFTSHIFT expr
- | '(' expr ')'"""
- pass
-
-def p_literal(p):
- """literal : STRING
- | NUMBER
- | FLOATNUMBER
- | LIT_BOOL"""
- pass
-
-def p_enumeration(p):
- "enumeration : ident ':' ident"
- pass
-
-def p_var(p):
- "var : ident"
- pass
-
-lex.lex()
-yacc.yacc(write_tables=0)
-
-slicc_generated_cc = set([
- 'ControllerFactory.cc',
- 'MachineType.cc'])
-
-slicc_generated_hh = set([
- 'ControllerFactory.hh',
- 'MachineType.hh',
- 'Types.hh',
- 'protocol_name.hh' ])
-
-class Machine(object):
- def __init__(self, name, decls):
- self.name = name
- self.decls = decls
-
- def add(self, hh, cc):
- hh.add('%s_Controller.hh' % self.name)
- hh.add('%s_Profiler.hh' % self.name)
-
- cc.add('%s_Controller.cc' % self.name)
- cc.add('%s_Profiler.cc' % self.name)
- cc.add('%s_Transitions.cc' % self.name)
- cc.add('%s_Wakeup.cc' % self.name)
-
- for decl in self.decls:
- decl.add(hh, cc, self.name)
-
-class Declaration(object):
- hh = False
- cc = False
- def __init__(self, name):
- self.name = name
-
- def add(self, hh, cc, name=None):
- #print '>>>', type(self).__name__, self.name
- if name:
- name += '_'
- else:
- name = ""
- if self.hh:
- hh.add('%s%s.hh' % (name, self.name))
- if self.cc:
- cc.add('%s%s.cc' % (name, self.name))
-
-class Action(Declaration): pass
-class InPort(Declaration): pass
-class OutPort(Declaration): pass
-class Transition(Declaration): pass
-class Extern(Declaration): pass
-class Global(Declaration):
- hh = True
- cc = True
-class Struct(Declaration):
- hh = True
- cc = True
-class Enum(Declaration):
- hh = True
- cc = True
-class Object(Declaration): pass
-class Function(Declaration):
- cc = True
-
-def read_slicc(sources):
- if not isinstance(sources, (list,tuple)):
- sources = [ sources ]
-
- sm_files = []
- for source in sources:
- for sm_file in file(source, "r"):
- sm_file = sm_file.strip()
- if not sm_file:
- continue
- if sm_file.startswith("#"):
- continue
- sm_files.append(sm_file)
-
- return sm_files
-
-def scan(filenames):
- hh = slicc_generated_hh.copy()
- cc = slicc_generated_cc.copy()
-
- for filename in filenames:
- lex.lexer.lineno = 1
- try:
- print "parsing ",filename
- results = yacc.parse(file(filename, 'r').read())
- except (TokenError, ParseError), e:
- sys.exit("%s: %s:%d" % (e, filename, e.token.lineno))
-
- for result in results:
- result.add(hh, cc)
-
- return list(hh), list(cc)
-
-if __name__ == '__main__':
- import sys
-
- hh, cc = scan(read_slicc(sys.argv[1:]))
- hh.sort()
- cc.sort()
- print 'Headers:'
- for i in hh:
- print ' %s' % i
-
- print 'Sources:'
- for i in cc:
- print ' %s' % i
diff --git a/src/mem/slicc/parser/parser.yy b/src/mem/slicc/parser/parser.yy
deleted file mode 100644
index c8cef3b21..000000000
--- a/src/mem/slicc/parser/parser.yy
+++ /dev/null
@@ -1,360 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- *
- * */
-
-%{
-#include <string>
-#include <stdio.h>
-#include <assert.h>
-#include "mem/slicc/ast/ASTs.hh"
-#include <vector>
-
-#define YYMAXDEPTH 100000
-#define YYERROR_VERBOSE
-
-extern char* yytext;
-
-extern "C" void yyerror(char*);
-extern "C" int yylex();
-
-%}
-
-%union {
- string* str_ptr;
- Vector<string>* string_vector_ptr;
- std::vector<string*>* stdstring_vector_ptr;
-
- // Decls
- DeclAST* decl_ptr;
- DeclListAST* decl_list_ptr;
- Vector<DeclAST*>* decl_vector_ptr;
-
- // TypeField
- TypeFieldAST* type_field_ptr;
- Vector<TypeFieldAST*>* type_field_vector_ptr;
-
- // Type
- TypeAST* type_ptr;
- Vector<TypeAST*>* type_vector_ptr;
-
- // Formal Params
- FormalParamAST* formal_param_ptr;
- Vector<FormalParamAST*>* formal_param_vector_ptr;
-
- // Statements
- StatementAST* statement_ptr;
- StatementListAST* statement_list_ptr;
- Vector<StatementAST*>* statement_vector_ptr;
-
- // Pairs
- PairAST* pair_ptr;
- PairListAST* pair_list_ptr;
-
- // Expressions
- VarExprAST* var_expr_ptr;
- ExprAST* expr_ptr;
- Vector<ExprAST*>* expr_vector_ptr;
-}
-
-%type <type_ptr> type void type_or_void
-%type <type_vector_ptr> types type_list
-
- // Formal Params
-%type <formal_param_ptr> formal_param
-%type <formal_param_vector_ptr> formal_params formal_param_list
-
-%type <str_ptr> ident field
-%type <string_vector_ptr> ident_list idents
-
-%type <statement_ptr> statement if_statement
-%type <statement_list_ptr> statement_list
-%type <statement_vector_ptr> statements
-
-%type <decl_ptr> decl
-%type <decl_list_ptr> decl_list
-%type <decl_vector_ptr> decls
-
-%type <type_field_vector_ptr> type_members type_enums type_methods
-%type <type_field_ptr> type_member type_enum type_method
-
-%type <var_expr_ptr> var
-%type <expr_ptr> expr literal enumeration
-%type <expr_vector_ptr> expr_list
-
-%type <pair_ptr> pair
-%type <pair_list_ptr> pair_list pairs
-
-%token <str_ptr> IDENT STRING NUMBER FLOATNUMBER LIT_BOOL VOID
-%token <str_ptr> IMBED IMBED_TYPE
-%token CHIP THIS
-%token ASSIGN DOUBLE_COLON DOT SEMICOLON COLON
-%token GLOBAL_DECL MACHINE_DECL IN_PORT_DECL OUT_PORT_DECL
-%token PEEK ENQUEUE COPY_HEAD CHECK_ALLOCATE CHECK_STOP_SLOTS
-//%token DEQUEUE REMOVE_EARLY SKIP_EARLY PEEK_EARLY
-%token DEBUG_EXPR_TOKEN DEBUG_MSG_TOKEN
-%token ACTION_DECL TRANSITION_DECL TYPE_DECL STRUCT_DECL EXTERN_TYPE_DECL ENUM_DECL
-%token TYPE_FIELD OTHER IF ELSE RETURN NEW
-
-%token <str_ptr> EQ NE '<' '>' LE GE NOT AND OR PLUS DASH STAR SLASH RIGHTSHIFT LEFTSHIFT
-
-%left OR
-%left AND
-%nonassoc EQ NE
-%nonassoc '<' '>' GE LE
-%left PLUS DASH
-%left STAR SLASH
-%nonassoc NOT
-%nonassoc DOUBLE_COLON DOT '['
-
-%%
-
-file: decl_list { g_decl_list_ptr = $1; }
-
-decl_list: decls { $$ = new DeclListAST($1); }
-
-decls: decl decls { $2->insertAtTop($1); $$ = $2; }
- | { $$ = new Vector<DeclAST*>; }
- ;
-
-decl: MACHINE_DECL '(' ident pair_list ')' ':' formal_param_list '{' decl_list '}' { $$ = new MachineAST($3, $4, $7, $9); }
- | ACTION_DECL '(' ident pair_list ')' statement_list { $$ = new ActionDeclAST($3, $4, $6); }
- | IN_PORT_DECL '(' ident ',' type ',' var pair_list ')' statement_list { $$ = new InPortDeclAST($3, $5, $7, $8, $10); }
- | OUT_PORT_DECL '(' ident ',' type ',' var pair_list ')' SEMICOLON { $$ = new OutPortDeclAST($3, $5, $7, $8); }
- | TRANSITION_DECL '(' ident_list ',' ident_list ',' ident pair_list ')' ident_list { $$ = new TransitionDeclAST($3, $5, $7, $8, $10); }
- | TRANSITION_DECL '(' ident_list ',' ident_list pair_list ')' ident_list { $$ = new TransitionDeclAST($3, $5, NULL, $6, $8); }
- | EXTERN_TYPE_DECL '(' type pair_list ')' SEMICOLON { $4->addPair(new PairAST("external", "yes")); $$ = new TypeDeclAST($3, $4, NULL); }
- | EXTERN_TYPE_DECL '(' type pair_list ')' '{' type_methods '}' { $4->addPair(new PairAST("external", "yes")); $$ = new TypeDeclAST($3, $4, $7); }
- | GLOBAL_DECL '(' type pair_list ')' '{' type_members '}' { $4->addPair(new PairAST("global", "yes"));$$ = new TypeDeclAST($3, $4, $7); }
- | STRUCT_DECL '(' type pair_list ')' '{' type_members '}' { $$ = new TypeDeclAST($3, $4, $7); }
- | ENUM_DECL '(' type pair_list ')' '{' type_enums '}' { $4->addPair(new PairAST("enumeration", "yes")); $$ = new EnumDeclAST($3, $4, $7); }
- | type ident pair_list SEMICOLON { $$ = new ObjDeclAST($1, $2, $3); }
- | type ident '(' formal_param_list ')' pair_list SEMICOLON { $$ = new FuncDeclAST($1, $2, $4, $6, NULL); } // non-void function
- | void ident '(' formal_param_list ')' pair_list SEMICOLON { $$ = new FuncDeclAST($1, $2, $4, $6, NULL); } // void function
- | type ident '(' formal_param_list ')' pair_list statement_list { $$ = new FuncDeclAST($1, $2, $4, $6, $7); } // non-void function
- | void ident '(' formal_param_list ')' pair_list statement_list { $$ = new FuncDeclAST($1, $2, $4, $6, $7); } // void function
- ;
-
-// Type fields
-
-type_members: type_member type_members { $2->insertAtTop($1); $$ = $2; }
- | { $$ = new Vector<TypeFieldAST*>; }
- ;
-
-type_member: type ident pair_list SEMICOLON { $$ = new TypeFieldMemberAST($1, $2, $3, NULL); }
- | type ident ASSIGN expr SEMICOLON { $$ = new TypeFieldMemberAST($1, $2, new PairListAST(), $4); }
- ;
-
-// Methods
-type_methods: type_method type_methods { $2->insertAtTop($1); $$ = $2; }
- | { $$ = new Vector<TypeFieldAST*>; }
- ;
-
-type_method: type_or_void ident '(' type_list ')' pair_list SEMICOLON { $$ = new TypeFieldMethodAST($1, $2, $4, $6); }
- ;
-
-// Enum fields
-type_enums: type_enum type_enums { $2->insertAtTop($1); $$ = $2; }
- | { $$ = new Vector<TypeFieldAST*>; }
- ;
-
-type_enum: ident pair_list SEMICOLON { $$ = new TypeFieldEnumAST($1, $2); }
- ;
-
-// Type
-type_list : types { $$ = $1; }
- | { $$ = new Vector<TypeAST*>; }
- ;
-
-types : type ',' types { $3->insertAtTop($1); $$ = $3; }
- | type { $$ = new Vector<TypeAST*>; $$->insertAtTop($1); }
- ;
-
-type: ident { $$ = new TypeAST($1); }
- ;
-
-void: VOID { $$ = new TypeAST($1); }
- ;
-
-type_or_void: type { $$ = $1; }
- | void { $$ = $1; }
- ;
-
-// Formal Param
-formal_param_list : formal_params { $$ = $1; }
- | { $$ = new Vector<FormalParamAST*>; }
- ;
-
-formal_params : formal_param ',' formal_params { $3->insertAtTop($1); $$ = $3; }
- | formal_param { $$ = new Vector<FormalParamAST*>; $$->insertAtTop($1); }
- ;
-
-formal_param : type ident { $$ = new FormalParamAST($1, $2); }
- ;
-
-// Idents and lists
-ident: IDENT { $$ = $1; };
-
-ident_list: '{' idents '}' { $$ = $2; }
- | ident { $$ = new Vector<string>; $$->insertAtTop(*($1)); delete $1; }
- ;
-
-idents: ident SEMICOLON idents { $3->insertAtTop(*($1)); $$ = $3; delete $1; }
- | ident ',' idents { $3->insertAtTop(*($1)); $$ = $3; delete $1; }
- | ident idents { $2->insertAtTop(*($1)); $$ = $2; delete $1; }
- | { $$ = new Vector<string>; }
- ;
-
-// Pair and pair lists
-pair_list: ',' pairs { $$ = $2; }
- | { $$ = new PairListAST(); }
-
-pairs : pair ',' pairs { $3->addPair($1); $$ = $3; }
- | pair { $$ = new PairListAST(); $$->addPair($1); }
- ;
-
-pair : ident '=' STRING { $$ = new PairAST($1, $3); }
- | ident '=' ident { $$ = new PairAST($1, $3); }
- | STRING { $$ = new PairAST(new string("short"), $1); }
- ;
-
-// Below are the rules for action descriptions
-
-statement_list: '{' statements '}' { $$ = new StatementListAST($2); }
- ;
-
-statements: statement statements { $2->insertAtTop($1); $$ = $2; }
- | { $$ = new Vector<StatementAST*>; }
- ;
-
-expr_list: expr ',' expr_list { $3->insertAtTop($1); $$ = $3; }
- | expr { $$ = new Vector<ExprAST*>; $$->insertAtTop($1); }
- | { $$ = new Vector<ExprAST*>; }
- ;
-
-statement: expr SEMICOLON { $$ = new ExprStatementAST($1); }
- | expr ASSIGN expr SEMICOLON { $$ = new AssignStatementAST($1, $3); }
- | ENQUEUE '(' var ',' type pair_list ')' statement_list { $$ = new EnqueueStatementAST($3, $5, $6, $8); }
- | PEEK '(' var ',' type ')' statement_list { $$ = new PeekStatementAST($3, $5, $7, "peek"); }
-// | PEEK_EARLY '(' var ',' type ')' statement_list { $$ = new PeekStatementAST($3, $5, $7, "peekEarly"); }
- | COPY_HEAD '(' var ',' var pair_list ')' SEMICOLON { $$ = new CopyHeadStatementAST($3, $5, $6); }
- | CHECK_ALLOCATE '(' var ')' SEMICOLON { $$ = new CheckAllocateStatementAST($3); }
- | CHECK_STOP_SLOTS '(' var ',' STRING ',' STRING ')' SEMICOLON { $$ = new CheckStopSlotsStatementAST($3, $5, $7); }
- | if_statement { $$ = $1; }
- | RETURN expr SEMICOLON { $$ = new ReturnStatementAST($2); }
- ;
-
-if_statement: IF '(' expr ')' statement_list ELSE statement_list { $$ = new IfStatementAST($3, $5, $7); }
- | IF '(' expr ')' statement_list { $$ = new IfStatementAST($3, $5, NULL); }
- | IF '(' expr ')' statement_list ELSE if_statement { $$ = new IfStatementAST($3, $5, new StatementListAST($7)); }
- ;
-
-expr: var { $$ = $1; }
- | literal { $$ = $1; }
- | enumeration { $$ = $1; }
- | ident '(' expr_list ')' { $$ = new FuncCallExprAST($1, $3); }
- | NEW type { $$ = new NewExprAST($2); }
-
-// globally access a local chip component and call a method
- | THIS DOT var '[' expr ']' DOT var DOT ident '(' expr_list ')' { $$ = new ChipComponentAccessAST($3, $5, $8, $10, $12 ); }
-// globally access a local chip component and access a data member
- | THIS DOT var '[' expr ']' DOT var DOT field { $$ = new ChipComponentAccessAST($3, $5, $8, $10 ); }
-// globally access a specified chip component and call a method
- | CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT ident '(' expr_list ')' { $$ = new ChipComponentAccessAST($3, $6, $8, $11, $13, $15 ); }
-// globally access a specified chip component and access a data member
- | CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT field { $$ = new ChipComponentAccessAST($3, $6, $8, $11, $13 ); }
-
-
- | expr DOT field { $$ = new MemberExprAST($1, $3); }
- | expr DOT ident '(' expr_list ')' { $$ = new MethodCallExprAST($1, $3, $5); }
- | type DOUBLE_COLON ident '(' expr_list ')' { $$ = new MethodCallExprAST($1, $3, $5); }
- | expr '[' expr_list ']' { $$ = new MethodCallExprAST($1, new string("lookup"), $3); }
- | expr STAR expr { $$ = new InfixOperatorExprAST($1, $2, $3); }
- | expr SLASH expr { $$ = new InfixOperatorExprAST($1, $2, $3); }
- | expr PLUS expr { $$ = new InfixOperatorExprAST($1, $2, $3); }
- | expr DASH expr { $$ = new InfixOperatorExprAST($1, $2, $3); }
- | expr '<' expr { $$ = new InfixOperatorExprAST($1, $2, $3); }
- | expr '>' expr { $$ = new InfixOperatorExprAST($1, $2, $3); }
- | expr LE expr { $$ = new InfixOperatorExprAST($1, $2, $3); }
- | expr GE expr { $$ = new InfixOperatorExprAST($1, $2, $3); }
- | expr EQ expr { $$ = new InfixOperatorExprAST($1, $2, $3); }
- | expr NE expr { $$ = new InfixOperatorExprAST($1, $2, $3); }
- | expr AND expr { $$ = new InfixOperatorExprAST($1, $2, $3); }
- | expr OR expr { $$ = new InfixOperatorExprAST($1, $2, $3); }
- | expr RIGHTSHIFT expr { $$ = new InfixOperatorExprAST($1, $2, $3); }
- | expr LEFTSHIFT expr { $$ = new InfixOperatorExprAST($1, $2, $3); }
-// | NOT expr { $$ = NULL; } // FIXME - unary not
-// | DASH expr %prec NOT { $$ = NULL; } // FIXME - unary minus
- | '(' expr ')' { $$ = $2; }
- ;
-
-literal: STRING { $$ = new LiteralExprAST($1, "string"); }
- | NUMBER { $$ = new LiteralExprAST($1, "int"); }
- | FLOATNUMBER { $$ = new LiteralExprAST($1, "int"); }
- | LIT_BOOL { $$ = new LiteralExprAST($1, "bool"); }
- ;
-
-enumeration: ident ':' ident { $$ = new EnumExprAST(new TypeAST($1), $3); }
- ;
-
-var: ident { $$ = new VarExprAST($1); }
- ;
-
-field: ident { $$ = $1; }
- ;
-
-%%
-
-extern FILE *yyin;
-
-DeclListAST* parse(string filename)
-{
- FILE *file;
- file = fopen(filename.c_str(), "r");
- if (!file) {
- cerr << "Error: Could not open file: " << filename << endl;
- exit(1);
- }
- g_line_number = 1;
- g_file_name() = filename;
- yyin = file;
- g_decl_list_ptr = NULL;
- yyparse();
- return g_decl_list_ptr;
-}
-
-extern "C" void yyerror(char* s)
-{
- fprintf(stderr, "%s:%d: %s at %s\n", g_file_name().c_str(), g_line_number, s, yytext);
- exit(1);
-}
-
diff --git a/src/mem/slicc/slicc_global.hh b/src/mem/slicc/slicc_global.hh
deleted file mode 100644
index 40a00c9d2..000000000
--- a/src/mem/slicc/slicc_global.hh
+++ /dev/null
@@ -1,125 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SLICC_GLOBAL_H
-#define SLICC_GLOBAL_H
-
-#include <cassert>
-
-#include "mem/gems_common/std-includes.hh"
-#include "mem/gems_common/Map.hh"
-
-typedef unsigned char uint8;
-typedef unsigned int uint32;
-typedef unsigned long long uint64;
-
-typedef signed char int8;
-typedef int int32;
-typedef long long int64;
-
-typedef long long integer_t;
-typedef unsigned long long uinteger_t;
-
-const bool ASSERT_FLAG = true;
-
-// when CHECK_RESOURCE_DEADLOCK is enabled, slicc will generate additional code
-// that works in conjuction with the resources rank value specified in the protocol
-// to detect invalid resource stalls as soon as they occur.
-const bool CHECK_INVALID_RESOURCE_STALLS = false;
-
-#undef assert
-#define assert(EXPR) ASSERT(EXPR)
-
-#define ASSERT(EXPR)\
-{\
- if (ASSERT_FLAG) {\
- if (!(EXPR)) {\
- cerr << "failed assertion '"\
- << #EXPR << "' at fn "\
- << __PRETTY_FUNCTION__ << " in "\
- << __FILE__ << ":"\
- << __LINE__ << endl;\
- if(isatty(STDERR_FILENO)) {\
- cerr << "At this point you might want to attach a debug to ";\
- cerr << "the running and get to the" << endl;\
- cerr << "crash site; otherwise press enter to continue" << endl;\
- cerr << "PID: " << getpid();\
- cerr << endl << flush; \
- char c; \
- cin.get(c); \
- }\
- abort();\
- }\
- }\
-}
-
-class State;
-class Event;
-class Symbol;
-class Var;
-
-namespace __gnu_cxx {
- template <> struct hash<State*>
- {
- size_t operator()(State* s) const { return (size_t) s; }
- };
- template <> struct hash<Event*>
- {
- size_t operator()(Event* s) const { return (size_t) s; }
- };
- template <> struct hash<Symbol*>
- {
- size_t operator()(Symbol* s) const { return (size_t) s; }
- };
- template <> struct hash<Var*>
- {
- size_t operator()(Var* s) const { return (size_t) s; }
- };
-} // namespace __gnu_cxx
-
-namespace std {
- template <> struct equal_to<Event*>
- {
- bool operator()(Event* s1, Event* s2) const { return s1 == s2; }
- };
- template <> struct equal_to<State*>
- {
- bool operator()(State* s1, State* s2) const { return s1 == s2; }
- };
- template <> struct equal_to<Symbol*>
- {
- bool operator()(Symbol* s1, Symbol* s2) const { return s1 == s2; }
- };
- template <> struct equal_to<Var*>
- {
- bool operator()(Var* s1, Var* s2) const { return s1 == s2; }
- };
-} // namespace std
-
-#endif //SLICC_GLOBAL_H
diff --git a/src/mem/slicc/symbols/Action.hh b/src/mem/slicc/symbols/Action.hh
deleted file mode 100644
index dbb0c836a..000000000
--- a/src/mem/slicc/symbols/Action.hh
+++ /dev/null
@@ -1,52 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- */
-
-#ifndef ACTION_H
-#define ACTION_H
-
-#include "mem/slicc/symbols/Symbol.hh"
-
-class Action : public Symbol {
-public:
- Action(string id,
- const Map<Var*, string>& resources,
- const Location& location,
- const Map<string, string>& pairs) : Symbol(id, location, pairs) { m_resources = resources; }
- const Map<Var*, string>& getResources() const { return m_resources; }
- void print(ostream& out) const { out << "[Action: " << getIdent() << "]"; }
-
-private:
- Map<Var*, string> m_resources;
-};
-
-#endif //ACTION_H
diff --git a/src/mem/slicc/symbols/Action.py b/src/mem/slicc/symbols/Action.py
new file mode 100644
index 000000000..880fab15a
--- /dev/null
+++ b/src/mem/slicc/symbols/Action.py
@@ -0,0 +1,38 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.symbols.Symbol import Symbol
+
+class Action(Symbol):
+ def __init__(self, table, ident, resources, location, pairs):
+ super(Action, self).__init__(table, ident, location, pairs)
+ self.resources = resources
+
+ def __repr__(self):
+ return "[Action: %s]" % self.ident
+
+__all__ = [ "Action" ]
diff --git a/src/mem/slicc/symbols/Event.hh b/src/mem/slicc/symbols/Event.hh
deleted file mode 100644
index 40cefc982..000000000
--- a/src/mem/slicc/symbols/Event.hh
+++ /dev/null
@@ -1,45 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- */
-
-#ifndef EVENT_H
-#define EVENT_H
-
-#include "mem/slicc/symbols/Symbol.hh"
-
-class Event : public Symbol {
-public:
- Event(string id, const Location& location, const Map<string, string>& pairs) : Symbol(id, location, pairs) {}
- void print(ostream& out) const { out << "[Event: " << getIdent() << "]"; }
-};
-
-#endif //EVENT_H
diff --git a/src/mem/slicc/symbols/Event.py b/src/mem/slicc/symbols/Event.py
new file mode 100644
index 000000000..9ff4d8ba7
--- /dev/null
+++ b/src/mem/slicc/symbols/Event.py
@@ -0,0 +1,34 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.symbols.Symbol import Symbol
+
+class Event(Symbol):
+ def __repr__(self):
+ return "[Event: %s]" % self.ident
+
+__all__ = [ "Event" ]
diff --git a/src/mem/slicc/symbols/Func.cc b/src/mem/slicc/symbols/Func.cc
deleted file mode 100644
index d29138b38..000000000
--- a/src/mem/slicc/symbols/Func.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Func.cc
- *
- * Description: See Func.hh
- *
- * $Id$
- *
- */
-
-#include "mem/slicc/symbols/Func.hh"
-#include "mem/slicc/symbols/SymbolTable.hh"
-#include "mem/slicc/generator/fileio.hh"
-#include "mem/slicc/symbols/StateMachine.hh"
-
-Func::Func(string id, const Location& location,
- Type* type_ptr, const Vector<Type*>& param_type_vec,
- const Vector<string>& param_string_vec, string body,
- const Map<string, string>& pairs, StateMachine* machine_ptr)
- : Symbol(id, location, pairs)
-{
- m_type_ptr = type_ptr;
- m_param_type_vec = param_type_vec;
- m_param_string_vec = param_string_vec;
- m_body = body;
- m_isInternalMachineFunc = false;
-
- if (machine_ptr == NULL) {
- m_c_ident = id;
- } else if (existPair("external") || existPair("primitive")) {
- m_c_ident = id;
- } else {
- m_machineStr = machine_ptr->toString();
- m_c_ident = m_machineStr + "_" + id; // Append with machine name
- m_isInternalMachineFunc = true;
- }
-}
-
-void Func::funcPrototype(string& code) const
-{
- if (isExternal()) {
- // Do nothing
- } else {
- string return_type = m_type_ptr->cIdent();
- Type* void_type_ptr = g_sym_table.getType("void");
- if (existPair("return_by_ref") && (m_type_ptr != void_type_ptr)) {
- return_type += "&";
- }
- code += return_type + " " + cIdent() + "(";
- int size = m_param_string_vec.size();
- for(int i=0; i<size; i++) {
- // Generate code
- if (i != 0) {
- code += ", ";
- }
- code += m_param_string_vec[i];
- }
- code += ");\n";
- }
-}
-
-// This write a function of object Chip
-void Func::writeCFiles(string path)
-{
- if (isExternal()) {
- // Do nothing
- } else {
- ostringstream out;
-
- // Header
- out << "/** Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< " */" << endl;
- out << endl;
- out << "#include \"mem/protocol/Types.hh\"" << endl;
- if (m_isInternalMachineFunc) {
- out << "#include \"mem/protocol/" << m_machineStr << "_Controller.hh\"" << endl;
- }
- out << endl;
-
- // Generate function header
- string code;
- Type* void_type_ptr = g_sym_table.getType("void");
- string return_type = m_type_ptr->cIdent();
- code += return_type;
- if (existPair("return_by_ref") && m_type_ptr != void_type_ptr) {
- code += "&";
- }
- if (!m_isInternalMachineFunc) {
- code += " Chip::" + cIdent() + "(";
- } else {
- code += " " + m_machineStr + "_Controller::" + cIdent() + "(";
- }
- int size = m_param_type_vec.size();
- for(int i=0; i<size; i++) {
- // Generate code
- if (i != 0) {
- code += ", ";
- }
- code += m_param_string_vec[i];
- }
- code += ")";
-
- // Function body
- code += "\n{\n";
- code += m_body;
- code += "}\n";
- out << code << endl;
-
- // Write it out
- conditionally_write_file(path + cIdent() + ".cc", out);
- }
-}
-
-void Func::print(ostream& out) const
-{
-}
diff --git a/src/mem/slicc/symbols/Func.hh b/src/mem/slicc/symbols/Func.hh
deleted file mode 100644
index 8f8548bb0..000000000
--- a/src/mem/slicc/symbols/Func.hh
+++ /dev/null
@@ -1,96 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Func.hh
- *
- * Description:
- *
- * $Id$
- *
- */
-
-#ifndef FUNC_H
-#define FUNC_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/symbols/Type.hh"
-class StateMachine;
-
-class Func : public Symbol {
-public:
- // Constructors
- Func(string id, const Location& location,
- Type* type_ptr, const Vector<Type*>& param_type_vec, const Vector<string>& param_string_vec,
- string body, const Map<string, string>& pairs, StateMachine* machine_ptr);
-
- // Destructor
- ~Func() {}
-
- // Public Methods
- string cIdent() const { return m_c_ident; }
- const Vector<Type*>& getParamTypes() const { return m_param_type_vec; }
- Type* getReturnType() const { return m_type_ptr; }
- void writeCFiles(string path) ;
- void funcPrototype(string& code) const;
- bool isExternal() const { return existPair("external"); }
- bool isInternalMachineFunc() const { return m_isInternalMachineFunc; }
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- Func(const Func& obj);
- Func& operator=(const Func& obj);
-
- // Data Members (m_ prefix)
- Type* m_type_ptr;
- Vector<Type*> m_param_type_vec;
- Vector<string> m_param_string_vec;
- string m_body;
- string m_c_ident;
- string m_machineStr;
- bool m_isInternalMachineFunc;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const Func& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const Func& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //FUNC_H
diff --git a/src/mem/slicc/symbols/Func.py b/src/mem/slicc/symbols/Func.py
new file mode 100644
index 000000000..5c812a96f
--- /dev/null
+++ b/src/mem/slicc/symbols/Func.py
@@ -0,0 +1,107 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.util import code_formatter
+
+from slicc.symbols.Symbol import Symbol
+from slicc.symbols.Type import Type
+
+class Func(Symbol):
+ def __init__(self, table, ident, location, return_type, param_types,
+ param_strings, body, pairs, machine):
+ super(Func, self).__init__(table, ident, location, pairs)
+ self.return_type = return_type
+ self.param_types = param_types
+ self.param_strings = param_strings
+ self.body = body
+ self.isInternalMachineFunc = False
+
+ if machine is None:
+ self.c_ident = ident
+ elif "external" in self or "primitive" in self:
+ self.c_ident = ident
+ else:
+ self.machineStr = str(machine)
+ # Append with machine name
+ self.c_ident = "%s_%s" % (self.machineStr, ident)
+ self.isInternalMachineFunc = True
+
+ def __repr__(self):
+ return ""
+
+ @property
+ def prototype(self):
+ if "external" in self:
+ return ""
+
+ return_type = self.return_type.c_ident
+ void_type = self.symtab.find("void", Type)
+ if "return_by_ref" in self and self.return_type != void_type:
+ return_type += "&"
+
+ return "%s %s(%s);" % (return_type, self.c_ident,
+ ", ".join(self.param_strings))
+
+ def writeCodeFiles(self, path):
+ '''This write a function of object Chip'''
+ if "external" in self:
+ return
+
+ code = code_formatter()
+
+ # Header
+ code('''
+/** Auto generated C++ code started by $__file__:$__line__ */
+
+#include "mem/protocol/Types.hh"
+''')
+
+ if self.isInternalMachineFunc:
+ code('#include "mem/protocol/${{self.machineStr}}_Controller.hh"')
+
+ # Generate function header
+ void_type = self.symtab.find("void", Type)
+ return_type = self.return_type.c_ident
+ if "return_by_ref" in self and self.return_type != void_type:
+ return_type += "&"
+
+ if self.isInternalMachineFunc:
+ klass = "%s_Controller" % self.machineStr
+ else:
+ klass = "Chip"
+
+ params = ', '.join(self.param_strings)
+
+ code('''
+$return_type ${klass}::${{self.c_ident}}($params)
+{
+${{self.body}}
+}
+''')
+ code.write(path, "%s.cc" % self.c_ident)
+
+__all__ = [ "Func" ]
diff --git a/src/mem/slicc/symbols/State.hh b/src/mem/slicc/symbols/State.hh
deleted file mode 100644
index 39900d506..000000000
--- a/src/mem/slicc/symbols/State.hh
+++ /dev/null
@@ -1,45 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- */
-
-#ifndef STATE_H
-#define STATE_H
-
-#include "mem/slicc/symbols/Symbol.hh"
-
-class State : public Symbol {
-public:
- State(string id, const Location& location, const Map<string, string>& pairs) : Symbol(id, location, pairs) {}
- void print(ostream& out) const { out << "[State: " << getIdent() << "]"; }
-};
-
-#endif //STATE_H
diff --git a/src/mem/slicc/symbols/State.py b/src/mem/slicc/symbols/State.py
new file mode 100644
index 000000000..123693256
--- /dev/null
+++ b/src/mem/slicc/symbols/State.py
@@ -0,0 +1,34 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.symbols.Symbol import Symbol
+
+class State(Symbol):
+ def __repr__(self):
+ return "[State: %s]" % self.ident
+
+__all__ = [ "State" ]
diff --git a/src/mem/slicc/symbols/StateMachine.cc b/src/mem/slicc/symbols/StateMachine.cc
deleted file mode 100644
index 0edfedc43..000000000
--- a/src/mem/slicc/symbols/StateMachine.cc
+++ /dev/null
@@ -1,1481 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- *
- * */
-
-#include "mem/slicc/symbols/StateMachine.hh"
-#include "mem/slicc/generator/fileio.hh"
-#include "mem/slicc/generator/html_gen.hh"
-#include "mem/slicc/symbols/Action.hh"
-#include "mem/slicc/symbols/Event.hh"
-#include "mem/slicc/symbols/State.hh"
-#include "mem/slicc/symbols/Transition.hh"
-#include "mem/slicc/symbols/Var.hh"
-#include "mem/slicc/symbols/SymbolTable.hh"
-#include "mem/gems_common/util.hh"
-#include "mem/gems_common/Vector.hh"
-#include "mem/slicc/ast/FormalParamAST.hh"
-
-#include <set>
-
-StateMachine::StateMachine(string ident, const Location& location, const Map<string, string>& pairs, Vector<FormalParamAST*>* config_parameters)
- : Symbol(ident, location, pairs)
-{
- m_table_built = false;
- m_config_parameters = config_parameters;
-
- for (int i=0; i< m_config_parameters->size(); i++) {
- Var* var = new Var(m_config_parameters->ref(i)->getName(),
- location,
- m_config_parameters->ref(i)->getType(),
- "m_"+m_config_parameters->ref(i)->getName(),
- Map<string, string>(),
- this);
- g_sym_table.registerSym(m_config_parameters->ref(i)->getName(), var);
- }
-}
-
-StateMachine::~StateMachine()
-{
- // FIXME
- // assert(0);
-}
-
-void StateMachine::addState(State* state_ptr)
-{
- assert(m_table_built == false);
- m_state_map.add(state_ptr, m_states.size());
- m_states.insertAtBottom(state_ptr);
-}
-
-void StateMachine::addEvent(Event* event_ptr)
-{
- assert(m_table_built == false);
- m_event_map.add(event_ptr, m_events.size());
- m_events.insertAtBottom(event_ptr);
-}
-
-void StateMachine::addAction(Action* action_ptr)
-{
- assert(m_table_built == false);
-
- // Check for duplicate action
- int size = m_actions.size();
- for(int i=0; i<size; i++) {
- if (m_actions[i]->getIdent() == action_ptr->getIdent()) {
- m_actions[i]->warning("Duplicate action definition: " + m_actions[i]->getIdent());
- action_ptr->error("Duplicate action definition: " + action_ptr->getIdent());
- }
- if (m_actions[i]->getShorthand() == action_ptr->getShorthand()) {
- m_actions[i]->warning("Duplicate action shorthand: " + m_actions[i]->getIdent());
- m_actions[i]->warning(" shorthand = " + m_actions[i]->getShorthand());
- action_ptr->warning("Duplicate action shorthand: " + action_ptr->getIdent());
- action_ptr->error(" shorthand = " + action_ptr->getShorthand());
- }
- }
-
- m_actions.insertAtBottom(action_ptr);
-}
-
-void StateMachine::addTransition(Transition* trans_ptr)
-{
- assert(m_table_built == false);
- trans_ptr->checkIdents(m_states, m_events, m_actions);
- m_transitions.insertAtBottom(trans_ptr);
-}
-
-void StateMachine::addFunc(Func* func_ptr)
-{
- // register func in the symbol table
- g_sym_table.registerSym(func_ptr->toString(), func_ptr);
- m_internal_func_vec.insertAtBottom(func_ptr);
-}
-
-void StateMachine::buildTable()
-{
- assert(m_table_built == false);
- int numStates = m_states.size();
- int numEvents = m_events.size();
- int numTransitions = m_transitions.size();
- int stateIndex, eventIndex;
-
- for(stateIndex=0; stateIndex < numStates; stateIndex++) {
- m_table.insertAtBottom(Vector<Transition*>());
- for(eventIndex=0; eventIndex < numEvents; eventIndex++) {
- m_table[stateIndex].insertAtBottom(NULL);
- }
- }
-
- for(int i=0; i<numTransitions; i++) {
- Transition* trans_ptr = m_transitions[i];
-
- // Track which actions we touch so we know if we use them all --
- // really this should be done for all symbols as part of the
- // symbol table, then only trigger it for Actions, States, Events,
- // etc.
-
- Vector<Action*> actions = trans_ptr->getActions();
- for(int actionIndex=0; actionIndex < actions.size(); actionIndex++) {
- actions[actionIndex]->markUsed();
- }
-
- stateIndex = getStateIndex(trans_ptr->getStatePtr());
- eventIndex = getEventIndex(trans_ptr->getEventPtr());
- if (m_table[stateIndex][eventIndex] != NULL) {
- m_table[stateIndex][eventIndex]->warning("Duplicate transition: " + m_table[stateIndex][eventIndex]->toString());
- trans_ptr->error("Duplicate transition: " + trans_ptr->toString());
- }
- m_table[stateIndex][eventIndex] = trans_ptr;
- }
-
- // Look at all actions to make sure we used them all
- for(int actionIndex=0; actionIndex < m_actions.size(); actionIndex++) {
- Action* action_ptr = m_actions[actionIndex];
- if (!action_ptr->wasUsed()) {
- string error_msg = "Unused action: " + action_ptr->getIdent();
- if (action_ptr->existPair("desc")) {
- error_msg += ", " + action_ptr->getDescription();
- }
- action_ptr->warning(error_msg);
- }
- }
-
- m_table_built = true;
-}
-
-const Transition* StateMachine::getTransPtr(int stateIndex, int eventIndex) const
-{
- return m_table[stateIndex][eventIndex];
-}
-
-// *********************** //
-// ******* C Files ******* //
-// *********************** //
-
-void StateMachine::writeCFiles(string path)
-{
- string comp = getIdent();
- string filename;
-
- // Output the method declarations for the class declaration
- {
- ostringstream sstr;
- printControllerH(sstr, comp);
- conditionally_write_file(path + comp + "_Controller.hh", sstr);
- }
-
- // Output switch statement for transition table
- {
- ostringstream sstr;
- printCSwitch(sstr, comp);
- conditionally_write_file(path + comp + "_Transitions.cc", sstr);
- }
-
- // Output the actions for performing the actions
- {
- ostringstream sstr;
- printControllerC(sstr, comp);
- conditionally_write_file(path + comp + "_Controller.cc", sstr);
- }
-
- // Output the wakeup loop for the events
- {
- ostringstream sstr;
- printCWakeup(sstr, comp);
- conditionally_write_file(path + comp + "_Wakeup.cc", sstr);
- }
-
- // Profiling
- {
- ostringstream sstr;
- printProfilerC(sstr, comp);
- conditionally_write_file(path + comp + "_Profiler.cc", sstr);
- }
- {
- ostringstream sstr;
- printProfilerH(sstr, comp);
- conditionally_write_file(path + comp + "_Profiler.hh", sstr);
- }
-
- // Write internal func files
- for(int i=0; i<m_internal_func_vec.size(); i++) {
- m_internal_func_vec[i]->writeCFiles(path);
- }
-
-}
-
-void StateMachine::printControllerH(ostream& out, string component)
-{
-
- m_message_buffer_names.clear();
-
- out << "/** \\file " << getIdent() << ".hh" << endl;
- out << " * " << endl;
- out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
- out << " * Created by slicc definition of Module \"" << getShorthand() << "\"" << endl;
- out << " */" << endl;
- out << endl;
- out << "#ifndef " << component << "_CONTROLLER_H" << endl;
- out << "#define " << component << "_CONTROLLER_H" << endl;
- out << endl;
- out << "#include \"mem/ruby/common/Global.hh\"" << endl;
- out << "#include \"mem/ruby/common/Consumer.hh\"" << endl;
- out << "#include \"mem/ruby/slicc_interface/AbstractController.hh\"" << endl;
- out << "#include \"mem/protocol/TransitionResult.hh\"" << endl;
- out << "#include \"mem/protocol/Types.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_Profiler.hh\"" << endl;
-
- // include object classes
- std::set<string> seen_types;
- for(int i=0; i<numObjects(); i++) {
- Var* var = m_objs[i];
- if (seen_types.count(var->getType()->cIdent()) == 0) {
- out << "#include \"mem/protocol/" << var->getType()->cIdent() << ".hh\"" << endl;
- // out << "class " << var->getType()->cIdent() << ";" << endl;
- seen_types.insert(var->getType()->cIdent());
- }
- }
-
- out << endl;
-
- // for adding information to the protocol debug trace
- out << "extern stringstream " << component << "_" << "transitionComment;" << endl;
-
- out << "class " << component << "_Controller : public AbstractController {" << endl;
-
- /* the coherence checker needs to call isBlockExclusive() and isBlockShared()
- making the Chip a friend class is an easy way to do this for now */
- out << "#ifdef CHECK_COHERENCE" << endl;
- out << "#endif /* CHECK_COHERENCE */" << endl;
-
- out << "public:" << endl;
- // out << " " << component << "_Controller(int version, Network* net_ptr);" << endl;
- out << " " << component << "_Controller(const string & name);" << endl;
- out << " static int getNumControllers();" << endl;
- out << " void init(Network* net_ptr, const vector<string> & argv);" << endl;
- out << " MessageBuffer* getMandatoryQueue() const;" << endl;
- out << " const int & getVersion() const;" << endl;
- out << " const string toString() const;" << endl;
- out << " const string getName() const;" << endl;
- out << " const MachineType getMachineType() const;" << endl;
- out << " void print(ostream& out) const;" << endl;
- out << " void printConfig(ostream& out) const;" << endl;
- out << " void wakeup();" << endl;
- out << " void set_atomic(Address addr);" << endl;
- out << " void clear_atomic(Address addr);" << endl;
- out << " void reset_atomics();" << endl;
- out << " void printStats(ostream& out) const { s_profiler.dumpStats(out); }" << endl;
- out << " void clearStats() { s_profiler.clearStats(); }" << endl;
- out << "private:" << endl;
-//added by SS
-// found_to_mem = 0;
- for(int i=0;i<m_config_parameters->size();i++){
- out << " int m_" << m_config_parameters->ref(i)->getName() << ";" << endl;
- }
- if (strncmp(component.c_str(), "L1Cache", 7) == 0) {
- out << " int servicing_atomic;" << endl;
- out << " bool started_receiving_writes;" << endl;
- out << " Address locked_read_request1;" << endl;
- out << " Address locked_read_request2;" << endl;
- out << " Address locked_read_request3;" << endl;
- out << " Address locked_read_request4;" << endl;
- out << " int read_counter;" << endl;
- }
- out << " int m_number_of_TBEs;" << endl;
-
- out << " TransitionResult doTransition(" << component << "_Event event, " << component
- << "_State state, const Address& addr";
- if(CHECK_INVALID_RESOURCE_STALLS) {
- out << ", int priority";
- }
- out << "); // in " << component << "_Transitions.cc" << endl;
- out << " TransitionResult doTransitionWorker(" << component << "_Event event, " << component
- << "_State state, " << component << "_State& next_state, const Address& addr";
- if(CHECK_INVALID_RESOURCE_STALLS) {
- out << ", int priority";
- }
- out << "); // in " << component << "_Transitions.cc" << endl;
- out << " string m_name;" << endl;
- out << " int m_transitions_per_cycle;" << endl;
- out << " int m_buffer_size;" << endl;
- out << " int m_recycle_latency;" << endl;
- out << " map< string, string > m_cfg;" << endl;
- out << " NodeID m_version;" << endl;
- out << " Network* m_net_ptr;" << endl;
- out << " MachineID m_machineID;" << endl;
- out << " " << component << "_Profiler s_profiler;" << endl;
- out << " static int m_num_controllers;" << endl;
-
- // internal function protypes
- out << " // Internal functions" << endl;
- for(int i=0; i<m_internal_func_vec.size(); i++) {
- Func* func = m_internal_func_vec[i];
- string proto;
- func->funcPrototype(proto);
- if (proto != "") {
- out << " " << proto;
- }
- }
-
- out << " // Actions" << endl;
- for(int i=0; i < numActions(); i++) {
- const Action& action = getAction(i);
- out << "/** \\brief " << action.getDescription() << "*/" << endl;
- out << " void " << action.getIdent() << "(const Address& addr);" << endl;
- }
-
- // the controller internal variables
- out << " // Object" << endl;
- for(int i=0; i < numObjects(); i++) {
- const Var* var = m_objs[i];
- string template_hack = "";
- if (var->existPair("template_hack")) {
- template_hack = var->lookupPair("template_hack");
- }
- out << " " << var->getType()->cIdent() << template_hack << "* m_"
- << var->cIdent() << "_ptr;" << endl;
-
- string str = "m_"+ var->cIdent() + "_ptr";
- if (var->getType()->cIdent() == "MessageBuffer")
- m_message_buffer_names.push_back(str);
-
- }
-
-
- out << "};" << endl;
- out << "#endif // " << component << "_CONTROLLER_H" << endl;
-}
-
-void StateMachine::printControllerC(ostream& out, string component)
-{
- out << "/** \\file " << getIdent() << ".cc" << endl;
- out << " * " << endl;
- out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
- out << " * Created by slicc definition of Module \"" << getShorthand() << "\"" << endl;
- out << " */" << endl;
- out << endl;
- out << "#include \"mem/ruby/common/Global.hh\"" << endl;
- out << "#include \"mem/ruby/slicc_interface/RubySlicc_includes.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_Controller.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_State.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_Event.hh\"" << endl;
- out << "#include \"mem/protocol/Types.hh\"" << endl;
- out << "#include \"mem/ruby/system/System.hh\"" << endl;
-
- // include object classes
- std::set<string> seen_types;
- for(int i=0; i<numObjects(); i++) {
- Var* var = m_objs[i];
- if (seen_types.count(var->getType()->cIdent()) == 0) {
- out << "#include \"mem/protocol/" << var->getType()->cIdent() << ".hh\"" << endl;
- seen_types.insert(var->getType()->cIdent());
- }
-
- }
-
- out << endl;
-
- out << "int " << component << "_Controller::m_num_controllers = 0;" << endl;
-
- // for adding information to the protocol debug trace
- out << "stringstream " << component << "_" << "transitionComment;" << endl;
- out << "#define APPEND_TRANSITION_COMMENT(str) (" << component << "_" << "transitionComment << str)" << endl;
-
- out << "/** \\brief constructor */" << endl;
- out << component << "_Controller::" << component
- // << "_Controller(int version, Network* net_ptr)" << endl;
- << "_Controller(const string & name)" << endl;
- out << " : m_name(name)" << endl;
- out << "{ " << endl;
- if (strncmp(component.c_str(), "L1Cache", 7) == 0) {
- out << " servicing_atomic = 0;" << endl;
- out << " started_receiving_writes = false;" << endl;
- out << " locked_read_request1 = Address(-1);" << endl;
- out << " locked_read_request2 = Address(-1);" << endl;
- out << " locked_read_request3 = Address(-1);" << endl;
- out << " locked_read_request4 = Address(-1);" << endl;
- out << " read_counter = 0;" << endl;
- }
- out << " m_num_controllers++; " << endl;
- for(int i=0; i < numObjects(); i++) {
- const Var* var = m_objs[i];
- if ( var->cIdent().find("mandatoryQueue") != string::npos)
- out << " m_" << var->cIdent() << "_ptr = new " << var->getType()->cIdent() << "();" << endl;
- }
- out << "}" << endl << endl;
-
- out << "void " << component << "_Controller::init(Network * net_ptr, const vector<string> & argv)" << endl;
- out << "{" << endl;
- out << " for (size_t i=0; i < argv.size(); i+=2) {" << endl;
-// out << " printf (\"ARG: %s = %s \\n \", argv[i].c_str(), argv[i+1].c_str());"<< endl;
-
- out << " if (argv[i] == \"version\") " << endl;
- out << " m_version = atoi(argv[i+1].c_str());" << endl;
- out << " else if (argv[i] == \"transitions_per_cycle\") " << endl;
- out << " m_transitions_per_cycle = atoi(argv[i+1].c_str());" << endl;
- out << " else if (argv[i] == \"buffer_size\") " << endl;
- out << " m_buffer_size = atoi(argv[i+1].c_str());" << endl;
-//added by SS
- out << " else if (argv[i] == \"recycle_latency\") " << endl;
- out << " m_recycle_latency = atoi(argv[i+1].c_str());" << endl;
-//added by SS --> for latency
-//for loop on latency_vector to check with argv[i] and assign the value to the related m_latency ...
- out << " else if (argv[i] == \"number_of_TBEs\") " << endl;
- out << " m_number_of_TBEs = atoi(argv[i+1].c_str());" << endl;
-
- if (m_config_parameters->size()) {
- for(int i= 0 ; i < m_config_parameters->size(); i++) {
- out << " else if (argv[i] == \"" << m_config_parameters->ref(i)->getName() << "\")" << endl;
- if (m_config_parameters->ref(i)->getTypeName() == "int")
- out << " m_" << m_config_parameters->ref(i)->getName() << "=" << "atoi(argv[i+1].c_str());" << endl;
- else
- assert(0); // only int parameters are supported right now
- // if (str == "to_mem_ctrl_latency")
- // out << " m_" << (*it)->c_str() << "=" << "atoi(argv[i+1].c_str())+(random() % 5);" << endl;
- }
- }
- out << " }" << endl;
- out << " m_net_ptr = net_ptr;" << endl;
- out << " m_machineID.type = MachineType_" << component << ";" << endl;
- out << " m_machineID.num = m_version;" << endl;
-
- // make configuration array
- out << " for (size_t i=0; i < argv.size(); i+=2) {" << endl;
- out << " if (argv[i] != \"version\") " << endl;
- out << " m_cfg[argv[i]] = argv[i+1];" << endl;
- out << " }" << endl;
-
- out << endl;
-
- // initialize objects
- out << " // Objects" << endl;
- out << " s_profiler.setVersion(m_version);" << endl;
- for(int i=0; i < numObjects(); i++) {
- const Var* var = m_objs[i];
- if (!var->existPair("network")) {
- // Not a network port object
- if (var->getType()->existPair("primitive")) {
- out << " m_" << var->cIdent() << "_ptr = new " << var->getType()->cIdent() << ";\n";
- if (var->existPair("default")) {
- out << " (*m_" << var->cIdent() << "_ptr) = " << var->lookupPair("default") << ";\n";
- }
- out << " }\n";
-
- } else {
- // Normal Object
- string template_hack = "";
- if (var->existPair("template_hack")) {
- template_hack = var->lookupPair("template_hack");
- }
-//added by SS
- string str = "";
- int found = 0;
- if (var->existPair("factory")) {
- out << " m_" << var->cIdent() << "_ptr = " << var->lookupPair("factory");
- } else {
- if ( var->cIdent().find("mandatoryQueue") == string::npos) {
-
- str = " m_" + var->cIdent() + "_ptr = new " + var->getType()->cIdent() + template_hack;
- out << str;
- if (str.find("TBETable")!=string::npos){
- found = 1;
- }
-
- if (!var->getType()->existPair("non_obj") && (!var->getType()->isEnumeration())) {
- str = "";
- if (var->existPair("constructor_hack")) {
- string constructor_hack = var->lookupPair("constructor_hack");
- str = "(" + constructor_hack + ")";
- } else {
- str = "()";
- }
- if (found)
- str = "(m_number_of_TBEs)";
- out << str;
- }
- }
- }
-
- out << ";\n";
- out << " assert(m_" << var->cIdent() << "_ptr != NULL);" << endl;
-
- if (var->existPair("default")) {
- out << " (*m_" << var->cIdent() << "_ptr) = " << var->lookupPair("default")
- << "; // Object default" << endl;
- } else if (var->getType()->hasDefault()) {
- out << " (*m_" << var->cIdent() << "_ptr) = " << var->getType()->getDefault()
- << "; // Type " << var->getType()->getIdent() << " default" << endl;
- }
-
- // Set ordering
- if (var->existPair("ordered") && !var->existPair("trigger_queue")) {
- // A buffer
- string ordered = var->lookupPair("ordered");
- out << " m_" << var->cIdent() << "_ptr->setOrdering(" << ordered << ");\n";
- }
-
- // Set randomization
- if (var->existPair("random")) {
- // A buffer
- string value = var->lookupPair("random");
- out << " m_" << var->cIdent() << "_ptr->setRandomization(" << value << ");\n";
- }
-
- // Set Priority
- if (var->getType()->isBuffer() && var->existPair("rank") && !var->existPair("trigger_queue")) {
- string rank = var->lookupPair("rank");
- out << " m_" << var->cIdent() << "_ptr->setPriority(" << rank << ");\n";
- }
- }
- } else {
- // Network port object
- string network = var->lookupPair("network");
- string ordered = var->lookupPair("ordered");
- string vnet = var->lookupPair("virtual_network");
-
- assert (var->getMachine() != NULL);
- out << " m_" << var->cIdent() << "_ptr = m_net_ptr->get"
- << network << "NetQueue(m_version+MachineType_base_number(string_to_MachineType(\""
- << var->getMachine()->getIdent() << "\")), "
- << ordered << ", " << vnet << ");\n";
- out << " assert(m_" << var->cIdent() << "_ptr != NULL);" << endl;
-
- // Set ordering
- if (var->existPair("ordered")) {
- // A buffer
- string ordered = var->lookupPair("ordered");
- out << " m_" << var->cIdent() << "_ptr->setOrdering(" << ordered << ");\n";
- }
-
- // Set randomization
- if (var->existPair("random")) {
- // A buffer
- string value = var->lookupPair("random");
- out << " m_" << var->cIdent() << "_ptr->setRandomization(" << value << ");\n";
- }
-
- // Set Priority
- if (var->existPair("rank")) {
- string rank = var->lookupPair("rank");
- out << " m_" << var->cIdent() << "_ptr->setPriority(" << rank << ");\n";
- }
-
- // Set buffer size
- if (var->getType()->isBuffer()) {
- out << " if (m_buffer_size > 0) {\n";
- out << " m_" << var->cIdent() << "_ptr->setSize(m_buffer_size);\n";
- out << " }\n";
- }
-
- // set description (may be overriden later by port def)
- out << " m_" << var->cIdent()
- << "_ptr->setDescription(\"[Version \" + int_to_string(m_version) + \", "
- << component << ", name=" << var->cIdent() << "]\");" << endl;
- out << endl;
- }
- }
-
- // Set the queue consumers
- out << endl;
- for(int i=0; i < m_in_ports.size(); i++) {
- const Var* port = m_in_ports[i];
- out << " " << port->getCode() << ".setConsumer(this);" << endl;
- }
-
- // Set the queue descriptions
- out << endl;
- for(int i=0; i < m_in_ports.size(); i++) {
- const Var* port = m_in_ports[i];
- out << " " << port->getCode()
- << ".setDescription(\"[Version \" + int_to_string(m_version) + \", "
- << component << ", " << port->toString() << "]\");" << endl;
- }
-
- // Initialize the transition profiling
- out << endl;
- for(int i=0; i<numTransitions(); i++) {
- const Transition& t = getTransition(i);
- const Vector<Action*>& action_vec = t.getActions();
- int numActions = action_vec.size();
-
- // Figure out if we stall
- bool stall = false;
- for (int i=0; i<numActions; i++) {
- if(action_vec[i]->getIdent() == "z_stall") {
- stall = true;
- }
- }
-
- // Only possible if it is not a 'z' case
- if (!stall) {
- out << " s_profiler.possibleTransition(" << component << "_State_"
- << t.getStatePtr()->getIdent() << ", " << component << "_Event_"
- << t.getEventPtr()->getIdent() << ");" << endl;
- }
- }
-
- //added by SS to initialize recycle_latency of message buffers
- std::vector<std::string>::const_iterator it;
- for ( it=m_message_buffer_names.begin() ; it != m_message_buffer_names.end(); it++ ){
- out << " "<< (*it).c_str() << "->setRecycleLatency(m_recycle_latency);" << endl;
- }
-
-
- out << "}" << endl;
-
- out << endl;
-
- bool has_mandatory_q = false;
- for(int i=0; i < m_in_ports.size(); i++) {
- if (m_in_ports[i]->getCode().find("mandatoryQueue_ptr")!= string::npos)
- has_mandatory_q = true;
- }
-
- out << "int " << component << "_Controller::getNumControllers() {" << endl;
- out << " return m_num_controllers;" << endl;
- out << "}" << endl;
-
- out << endl;
-
- out << "MessageBuffer* " << component << "_Controller::getMandatoryQueue() const {" << endl;
- if (has_mandatory_q)
- out << " return m_" << component << "_mandatoryQueue_ptr;" << endl;
- else
- out << " return NULL;" << endl;
- out << "}" << endl;
-
- out << endl;
-
- out << "const int & "<<component<<"_Controller::getVersion() const{" << endl;
- out << " return m_version;" << endl;
- out << "}";
-
- out << endl;
-
- out << "const string "<<component<<"_Controller::toString() const{" << endl;
- out << " return \"" << component<< "_Controller\";" << endl;
- out << "}";
-
- out << endl;
-
- out << "const string "<<component<<"_Controller::getName() const{" << endl;
- out << " return m_name;" << endl;
- out << "}";
-
- out << endl;
-
- out << "const MachineType "<<component<<"_Controller::getMachineType() const{" << endl;
- out << " return MachineType_" << component<< ";" << endl;
- out << "}";
-
- out << endl;
-
- out << "void " << component << "_Controller::print(ostream& out) const { out << \"[" << component
- << "_Controller \" << m_version << \"]\"; }" << endl;
-
- out << "void " << component << "_Controller::printConfig(ostream& out) const {" << endl;
- out << " out << \"" << component << "_Controller config: \" << m_name << endl;" << endl;
- out << " out << \" version: \" << m_version << endl;" << endl;
- out << " for(map< string, string >::const_iterator it = m_cfg.begin(); it != m_cfg.end(); it++) {" << endl;
- out << " out << \" \" << (*it).first << \": \" << (*it).second << endl;" << endl;
- out << " }" << endl;
- out << "}" << endl;
-
- out << endl;
- out << "// Actions" << endl;
- out << endl;
-
- for(int i=0; i < numActions(); i++) {
- const Action& action = getAction(i);
- if (action.existPair("c_code")) {
- out << "/** \\brief " << action.getDescription() << "*/" << endl;
- out << "void " << component << "_Controller::"
- << action.getIdent() << "(const Address& addr)" << endl;
- out << "{" << endl;
- out << " DEBUG_MSG(GENERATED_COMP, HighPrio,\"executing\");" << endl;
-//added by SS
-//it should point to m_latency...
-//so I should change the string output of this lookup
-
-
- string c_code_string = action.lookupPair("c_code");
-
- out << c_code_string;
-
- out << "}" << endl;
- }
- out << endl;
- }
-}
-
-void StateMachine::printCWakeup(ostream& out, string component)
-{
- out << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
- out << "// " << getIdent() << ": " << getShorthand() << endl;
- out << endl;
- out << "#include \"mem/ruby/common/Global.hh\"" << endl;
- out << "#include \"mem/ruby/slicc_interface/RubySlicc_includes.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_Controller.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_State.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_Event.hh\"" << endl;
- out << "#include \"mem/protocol/Types.hh\"" << endl;
- out << "#include \"mem/ruby/system/System.hh\"" << endl;
- out << endl;
- out << "void " << component << "_Controller::wakeup()" << endl;
- out << "{" << endl;
- // out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,*this);" << endl;
- // out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,g_eventQueue_ptr->getTime());" << endl;
- out << endl;
- out << "int counter = 0;" << endl;
- out << " while (true) {" << endl;
- out << " // Some cases will put us into an infinite loop without this limit" << endl;
- out << " assert(counter <= m_transitions_per_cycle);" << endl;
- out << " if (counter == m_transitions_per_cycle) {" << endl;
- out << " g_system_ptr->getProfiler()->controllerBusy(m_machineID); // Count how often we're fully utilized" << endl;
- out << " g_eventQueue_ptr->scheduleEvent(this, 1); // Wakeup in another cycle and try again" << endl;
- out << " break;" << endl;
- out << " }" << endl;
-
- // InPorts
- //
- // Find the position of the mandatory queue in the vector so that we can print it out first
- int j = -1;
- if (strncmp(component.c_str(), "L1Cache", 7) == 0) {
- for(int i=0; i < m_in_ports.size(); i++) {
- const Var* port = m_in_ports[i];
- assert(port->existPair("c_code_in_port"));
- if (port->toString().find("mandatoryQueue_in") != string::npos) {
- assert (j == -1);
- j = i;
- }
- else {
- cout << port->toString() << endl << flush;
- }
- }
-
- assert(j != -1);
-
- // print out the mandatory queue here
- const Var* port = m_in_ports[j];
- assert(port->existPair("c_code_in_port"));
- out << " // "
- << component << "InPort " << port->toString()
- << endl;
- string output = port->lookupPair("c_code_in_port");
-
- out << output;
- out << endl;
- }
- for(int i=0; i < m_in_ports.size(); i++) {
- const Var* port = m_in_ports[i];
- // don't print out mandatory queue twice
- if (i != j) {
- if (strncmp(component.c_str(), "L1Cache", 7) == 0) {
- if (port->toString().find("forwardRequestNetwork_in") != string::npos) {
- out << " bool postpone = false;" << endl;
- out << " if ((((*m_L1Cache_forwardToCache_ptr)).isReady())) {" << endl;
- out << " const RequestMsg* in_msg_ptr;" << endl;
- out << " in_msg_ptr = dynamic_cast<const RequestMsg*>(((*m_L1Cache_forwardToCache_ptr)).peek());" << endl;
- out << " if ((((servicing_atomic > 0) && (locked_read_request1 == ((*in_msg_ptr)).m_Address || locked_read_request2 == ((*in_msg_ptr)).m_Address || locked_read_request3 == ((*in_msg_ptr)).m_Address || locked_read_request1 == ((*in_msg_ptr)).m_Address)))) {" << endl;
- out << " postpone = true;" << endl;
- out << " }" << endl;
-
- out << " }" << endl;
- out << " if (!postpone) {" << endl;
- }
- else if (port->toString().find("requestNetwork_in") != string::npos || port->toString().find("requestIntraChipL1Network_in") != string::npos) {
- out << " bool postpone = false;" << endl;
- out << " if ((((*m_L1Cache_requestToL1Cache_ptr)).isReady())) {" << endl;
- out << " const RequestMsg* in_msg_ptr;" << endl;
- out << " in_msg_ptr = dynamic_cast<const RequestMsg*>(((*m_L1Cache_requestToL1Cache_ptr)).peek());" << endl;
- out << " if ((((servicing_atomic > 0) && (locked_read_request1 == ((*in_msg_ptr)).m_Address || locked_read_request2 == ((*in_msg_ptr)).m_Address || locked_read_request3 == ((*in_msg_ptr)).m_Address || locked_read_request1 == ((*in_msg_ptr)).m_Address)))) {" << endl;
- out << " postpone = true;" << endl;
- out << " }" << endl;
-
- out << " }" << endl;
- out << " if (!postpone) {" << endl;
- }
- }
- assert(port->existPair("c_code_in_port"));
- out << " // "
- << component << "InPort " << port->toString()
- << endl;
- out << port->lookupPair("c_code_in_port");
- if (strncmp(component.c_str(), "L1Cache", 7) == 0) {
- if (port->toString().find("forwardRequestNetwork_in") != string::npos) {
- out << "}" << endl;
- }
- else if (port->toString().find("requestIntraChipL1Network_in") != string::npos) {
- out << "}" << endl;
- }
- else if (port->toString().find("requestNetwork_in") != string::npos) {
- out << "}" << endl;
- }
- }
- out << endl;
- }
- }
-
- out << " break; // If we got this far, we have nothing left todo" << endl;
- out << " }" << endl;
- // out << " g_eventQueue_ptr->scheduleEvent(this, 1);" << endl;
- // out << " DEBUG_NEWLINE(GENERATED_COMP, MedPrio);" << endl;
- out << "}" << endl;
- out << endl;
-
-
- // tack on two more functions
- if (strncmp(component.c_str(), "L1Cache", 7) == 0) {
- out << "void " << component << "_Controller::set_atomic(Address addr)" << endl;
- out << "{" << endl;
- out << " servicing_atomic++; " << endl;
- out << " switch (servicing_atomic) { " << endl;
- out << " case(1): " << endl;
- out << " assert(locked_read_request1 == Address(-1)); " << endl;
- out << " locked_read_request1 = addr; " << endl;
- out << " break; " << endl;
- out << " case(2): " << endl;
- out << " assert(locked_read_request2 == Address(-1)); " << endl;
- out << " locked_read_request2 = addr; " << endl;
- out << " break; " << endl;
- out << " case(3): " << endl;
- out << " assert(locked_read_request3 == Address(-1)); " << endl;
- out << " locked_read_request3 = addr; " << endl;
- out << " break; " << endl;
- out << " case(4): " << endl;
- out << " assert(locked_read_request4 == Address(-1)); " << endl;
- out << " locked_read_request4 = addr; " << endl;
- out << " break; " << endl;
- out << " default: " << endl;
- out << " assert(0);" << endl;
- out << " }" << endl;
- out << "}" << endl;
-
- out << "void " << component << "_Controller::clear_atomic(Address addr)" << endl;
- out << "{" << endl;
- out << " assert(servicing_atomic > 0); " << endl;
- out << " if (addr == locked_read_request1) " << endl;
- out << " locked_read_request1 = Address(-1);" << endl;
- out << " else if (addr == locked_read_request2)" << endl;
- out << " locked_read_request2 = Address(-1);" << endl;
- out << " else if (addr == locked_read_request3)" << endl;
- out << " locked_read_request3 = Address(-1);" << endl;
- out << " else if (addr == locked_read_request4)" << endl;
- out << " locked_read_request4 = Address(-1);" << endl;
- out << " else " << endl;
- out << " assert(0); " << endl;
- out << " servicing_atomic--; " << endl;
- out << "}" << endl;
-
- out << "void " << component << "_Controller::reset_atomics()" << endl;
- out << "{" << endl;
- out << " servicing_atomic = 0; " << endl;
- out << " locked_read_request1 = Address(-1);" << endl;
- out << " locked_read_request2 = Address(-1);" << endl;
- out << " locked_read_request3 = Address(-1);" << endl;
- out << " locked_read_request4 = Address(-1);" << endl;
- out << "}" << endl;
- }
- else {
- out << "void " << component << "_Controller::set_atomic(Address addr)" << endl;
- out << "{" << endl;
- out << " assert(0); " << endl;
- out << "}" << endl;
-
- out << "void " << component << "_Controller::clear_atomic(Address addr)" << endl;
- out << "{" << endl;
- out << " assert(0); " << endl;
- out << "}" << endl;
-
- out << "void " << component << "_Controller::reset_atomics()" << endl;
- out << "{" << endl;
- out << " assert(0); " << endl;
- out << "}" << endl;
- }
-
-}
-
-void StateMachine::printCSwitch(ostream& out, string component)
-{
- out << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
- out << "// " << getIdent() << ": " << getShorthand() << endl;
- out << endl;
- out << "#include \"mem/ruby/common/Global.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_Controller.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_State.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_Event.hh\"" << endl;
- out << "#include \"mem/protocol/Types.hh\"" << endl;
- out << "#include \"mem/ruby/system/System.hh\"" << endl;
- out << endl;
- out << "#define HASH_FUN(state, event) ((int(state)*" << component
- << "_Event_NUM)+int(event))" << endl;
- out << endl;
- out << "#define GET_TRANSITION_COMMENT() (" << component << "_" << "transitionComment.str())" << endl;
- out << "#define CLEAR_TRANSITION_COMMENT() (" << component << "_" << "transitionComment.str(\"\"))" << endl;
- out << endl;
- out << "TransitionResult " << component << "_Controller::doTransition("
- << component << "_Event event, "
- << component << "_State state, "
- << "const Address& addr" << endl;
- if(CHECK_INVALID_RESOURCE_STALLS) {
- out << ", int priority";
- }
- out << ")" << endl;
-
- out << "{" << endl;
- out << " " << component << "_State next_state = state;" << endl;
- out << endl;
- out << " DEBUG_NEWLINE(GENERATED_COMP, MedPrio);" << endl;
- out << " DEBUG_MSG(GENERATED_COMP, MedPrio,*this);" << endl;
- out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,g_eventQueue_ptr->getTime());" << endl;
- out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,state);" << endl;
- out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,event);" << endl;
- out << " DEBUG_EXPR(GENERATED_COMP, MedPrio,addr);" << endl;
- out << endl;
- out << " TransitionResult result = doTransitionWorker(event, state, next_state, addr";
- if(CHECK_INVALID_RESOURCE_STALLS) {
- out << ", priority";
- }
- out << ");" << endl;
- out << endl;
- out << " if (result == TransitionResult_Valid) {" << endl;
- out << " DEBUG_EXPR(GENERATED_COMP, MedPrio, next_state);" << endl;
- out << " DEBUG_NEWLINE(GENERATED_COMP, MedPrio);" << endl;
- out << " s_profiler.countTransition(state, event);" << endl;
- out << " if (Debug::getProtocolTrace()) {" << endl
- << " g_system_ptr->getProfiler()->profileTransition(\"" << component
- << "\", m_version, addr, " << endl
- << " " << component << "_State_to_string(state), " << endl
- << " " << component << "_Event_to_string(event), " << endl
- << " " << component << "_State_to_string(next_state), GET_TRANSITION_COMMENT());" << endl
- << " }" << endl;
- out << " CLEAR_TRANSITION_COMMENT();" << endl;
- out << " " << component << "_setState(addr, next_state);" << endl;
- out << " " << endl;
- out << " } else if (result == TransitionResult_ResourceStall) {" << endl;
- out << " if (Debug::getProtocolTrace()) {" << endl
- << " g_system_ptr->getProfiler()->profileTransition(\"" << component
- << "\", m_version, addr, " << endl
- << " " << component << "_State_to_string(state), " << endl
- << " " << component << "_Event_to_string(event), " << endl
- << " " << component << "_State_to_string(next_state), " << endl
- << " \"Resource Stall\");" << endl
- << " }" << endl;
- out << " } else if (result == TransitionResult_ProtocolStall) {" << endl;
- out << " DEBUG_MSG(GENERATED_COMP,HighPrio,\"stalling\");" << endl
- << " DEBUG_NEWLINE(GENERATED_COMP, MedPrio);" << endl;
- out << " if (Debug::getProtocolTrace()) {" << endl
- << " g_system_ptr->getProfiler()->profileTransition(\"" << component
- << "\", m_version, addr, " << endl
- << " " << component << "_State_to_string(state), " << endl
- << " " << component << "_Event_to_string(event), " << endl
- << " " << component << "_State_to_string(next_state), " << endl
- << " \"Protocol Stall\");" << endl
- << " }" << endl
- << " }" << endl;
- out << " return result;" << endl;
- out << "}" << endl;
- out << endl;
- out << "TransitionResult " << component << "_Controller::doTransitionWorker("
- << component << "_Event event, "
- << component << "_State state, "
- << component << "_State& next_state, "
- << "const Address& addr" << endl;
- if(CHECK_INVALID_RESOURCE_STALLS) {
- out << ", int priority" << endl;
- }
- out << ")" << endl;
-
- out << "{" << endl;
- out << "" << endl;
-
- out << " switch(HASH_FUN(state, event)) {" << endl;
-
- Map<string, Vector<string> > code_map; // This map will allow suppress generating duplicate code
- Vector<string> code_vec;
-
- for(int i=0; i<numTransitions(); i++) {
- const Transition& t = getTransition(i);
- string case_string = component + "_State_" + t.getStatePtr()->getIdent()
- + ", " + component + "_Event_" + t.getEventPtr()->getIdent();
-
- string code;
-
- code += " {\n";
- // Only set next_state if it changes
- if (t.getStatePtr() != t.getNextStatePtr()) {
- code += " next_state = " + component + "_State_" + t.getNextStatePtr()->getIdent() + ";\n";
- }
-
- const Vector<Action*>& action_vec = t.getActions();
- int numActions = action_vec.size();
-
- // Check for resources
- Vector<string> code_sorter;
- const Map<Var*, string>& res = t.getResources();
- Vector<Var*> res_keys = res.keys();
- for (int i=0; i<res_keys.size(); i++) {
- string temp_code;
- if (res_keys[i]->getType()->cIdent() == "DNUCAStopTable") {
- temp_code += res.lookup(res_keys[i]);
- } else {
- temp_code += " if (!" + (res_keys[i]->getCode()) + ".areNSlotsAvailable(" + res.lookup(res_keys[i]) + ")) {\n";
- if(CHECK_INVALID_RESOURCE_STALLS) {
- // assert that the resource stall is for a resource of equal or greater priority
- temp_code += " assert(priority >= "+ (res_keys[i]->getCode()) + ".getPriority());\n";
- }
- temp_code += " return TransitionResult_ResourceStall;\n";
- temp_code += " }\n";
- }
- code_sorter.insertAtBottom(temp_code);
- }
-
- // Emit the code sequences in a sorted order. This makes the
- // output deterministic (without this the output order can vary
- // since Map's keys() on a vector of pointers is not deterministic
- code_sorter.sortVector();
- for (int i=0; i<code_sorter.size(); i++) {
- code += code_sorter[i];
- }
-
- // Figure out if we stall
- bool stall = false;
- for (int i=0; i<numActions; i++) {
- if(action_vec[i]->getIdent() == "z_stall") {
- stall = true;
- }
- }
-
- if (stall) {
- code += " return TransitionResult_ProtocolStall;\n";
- } else {
- for (int i=0; i<numActions; i++) {
- code += " " + action_vec[i]->getIdent() + "(addr);\n";
- }
- code += " return TransitionResult_Valid;\n";
- }
- code += " }\n";
-
-
- // Look to see if this transition code is unique.
- if (code_map.exist(code)) {
- code_map.lookup(code).insertAtBottom(case_string);
- } else {
- Vector<string> vec;
- vec.insertAtBottom(case_string);
- code_map.add(code, vec);
- code_vec.insertAtBottom(code);
- }
- }
-
- // Walk through all of the unique code blocks and spit out the
- // corresponding case statement elements
- for (int i=0; i<code_vec.size(); i++) {
- string code = code_vec[i];
-
- // Iterative over all the multiple transitions that share the same code
- for (int case_num=0; case_num<code_map.lookup(code).size(); case_num++) {
- string case_string = code_map.lookup(code)[case_num];
- out << " case HASH_FUN(" << case_string << "):" << endl;
- }
- out << code;
- }
-
- out << " default:" << endl;
- out << " WARN_EXPR(m_version);" << endl;
- out << " WARN_EXPR(g_eventQueue_ptr->getTime());" << endl;
- out << " WARN_EXPR(addr);" << endl;
- out << " WARN_EXPR(event);" << endl;
- out << " WARN_EXPR(state);" << endl;
- out << " ERROR_MSG(\"Invalid transition\");" << endl;
- out << " }" << endl;
- out << " return TransitionResult_Valid;" << endl;
- out << "}" << endl;
-}
-
-void StateMachine::printProfilerH(ostream& out, string component)
-{
- out << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
- out << "// " << getIdent() << ": " << getShorthand() << endl;
- out << endl;
- out << "#ifndef " << component << "_PROFILER_H" << endl;
- out << "#define " << component << "_PROFILER_H" << endl;
- out << endl;
- out << "#include \"mem/ruby/common/Global.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_State.hh\"" << endl;
- out << "#include \"mem/protocol/" << component << "_Event.hh\"" << endl;
- out << endl;
- out << "class " << component << "_Profiler {" << endl;
- out << "public:" << endl;
- out << " " << component << "_Profiler();" << endl;
- out << " void setVersion(int version);" << endl;
- out << " void countTransition(" << component << "_State state, " << component << "_Event event);" << endl;
- out << " void possibleTransition(" << component << "_State state, " << component << "_Event event);" << endl;
- out << " void dumpStats(ostream& out) const;" << endl;
- out << " void clearStats();" << endl;
- out << "private:" << endl;
- out << " int m_counters[" << component << "_State_NUM][" << component << "_Event_NUM];" << endl;
- out << " int m_event_counters[" << component << "_Event_NUM];" << endl;
- out << " bool m_possible[" << component << "_State_NUM][" << component << "_Event_NUM];" << endl;
- out << " int m_version;" << endl;
- out << "};" << endl;
- out << "#endif // " << component << "_PROFILER_H" << endl;
-}
-
-void StateMachine::printProfilerC(ostream& out, string component)
-{
- out << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
- out << "// " << getIdent() << ": " << getShorthand() << endl;
- out << endl;
- out << "#include \"mem/protocol/" << component << "_Profiler.hh\"" << endl;
- out << endl;
-
- // Constructor
- out << component << "_Profiler::" << component << "_Profiler()" << endl;
- out << "{" << endl;
- out << " for (int state = 0; state < " << component << "_State_NUM; state++) {" << endl;
- out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl;
- out << " m_possible[state][event] = false;" << endl;
- out << " m_counters[state][event] = 0;" << endl;
- out << " }" << endl;
- out << " }" << endl;
- out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl;
- out << " m_event_counters[event] = 0;" << endl;
- out << " }" << endl;
- out << "}" << endl;
-
- // setVersion
- out << "void " << component << "_Profiler::setVersion(int version)" << endl;
- out << "{" << endl;
- out << " m_version = version;" << endl;
- out << "}" << endl;
-
- // Clearstats
- out << "void " << component << "_Profiler::clearStats()" << endl;
- out << "{" << endl;
- out << " for (int state = 0; state < " << component << "_State_NUM; state++) {" << endl;
- out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl;
- out << " m_counters[state][event] = 0;" << endl;
- out << " }" << endl;
- out << " }" << endl;
- out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl;
- out << " m_event_counters[event] = 0;" << endl;
- out << " }" << endl;
- out << "}" << endl;
-
- // Count Transition
- out << "void " << component << "_Profiler::countTransition(" << component << "_State state, " << component << "_Event event)" << endl;
- out << "{" << endl;
- out << " assert(m_possible[state][event]);" << endl;
- out << " m_counters[state][event]++;" << endl;
- out << " m_event_counters[event]++;" << endl;
- out << "}" << endl;
-
- // Possible Transition
- out << "void " << component << "_Profiler::possibleTransition(" << component << "_State state, " << component << "_Event event)" << endl;
- out << "{" << endl;
- out << " m_possible[state][event] = true;" << endl;
- out << "}" << endl;
-
- // dumpStats
- out << "void " << component << "_Profiler::dumpStats(ostream& out) const" << endl;
- out << "{" << endl;
- out << " out << \" --- " << component << " \" << m_version << \" ---\" << endl;" << endl;
- out << " out << \" - Event Counts -\" << endl;" << endl;
- out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl;
- out << " int count = m_event_counters[event];" << endl;
- out << " out << (" << component << "_Event) event << \" \" << count << endl;" << endl;
- out << " }" << endl;
- out << " out << endl;" << endl;
- out << " out << \" - Transitions -\" << endl;" << endl;
- out << " for (int state = 0; state < " << component << "_State_NUM; state++) {" << endl;
- out << " for (int event = 0; event < " << component << "_Event_NUM; event++) {" << endl;
- out << " if (m_possible[state][event]) {" << endl;
- out << " int count = m_counters[state][event];" << endl;
- out << " out << (" << component << "_State) state << \" \" << (" << component << "_Event) event << \" \" << count;" << endl;
- out << " if (count == 0) {" << endl;
- out << " out << \" <-- \";" << endl;
- out << " }" << endl;
- out << " out << endl;" << endl;
- out << " }" << endl;
- out << " }" << endl;
- out << " out << endl;" << endl;
- out << " }" << endl;
- out << "}" << endl;
-}
-
-
-
-// ************************** //
-// ******* HTML Files ******* //
-// ************************** //
-
-string frameRef(string click_href, string click_target, string over_href, string over_target_num, string text)
-{
- string temp;
- temp += "<A href=\"" + click_href + "\" ";
- temp += "target=\"" + click_target + "\" ";
- string javascript = "if (parent.frames[" + over_target_num + "].location != parent.location + '" + over_href + "') { parent.frames[" + over_target_num + "].location='" + over_href + "' }";
- // string javascript = "parent." + target + ".location='" + href + "'";
- temp += "onMouseOver=\"" + javascript + "\" ";
- temp += ">" + text + "</A>";
- return temp;
-}
-
-string frameRef(string href, string target, string target_num, string text)
-{
- return frameRef(href, target, href, target_num, text);
-}
-
-
-void StateMachine::writeHTMLFiles(string path)
-{
- string filename;
- string component = getIdent();
-
- /*
- {
- ostringstream out;
- out << "<html>" << endl;
- out << "<head>" << endl;
- out << "<title>" << component << "</title>" << endl;
- out << "</head>" << endl;
- out << "<frameset rows=\"30,30,*\" frameborder=\"1\">" << endl;
- out << " <frame name=\"Status\" src=\"empty.html\" marginheight=\"1\">" << endl;
- out << " <frame name=\"Table\" src=\"" << component << "_table.html\" marginheight=\"1\">" << endl;
- out << "</frameset>" << endl;
- out << "</html>" << endl;
- conditionally_write_file(path + component + ".html", out);
- }
- */
-
- // Create table with no row hilighted
- {
- ostringstream out;
- printHTMLTransitions(out, numStates()+1);
-
- // -- Write file
- filename = component + "_table.html";
- conditionally_write_file(path + filename, out);
- }
-
- // Generate transition tables
- for(int i=0; i<numStates(); i++) {
- ostringstream out;
- printHTMLTransitions(out, i);
-
- // -- Write file
- filename = component + "_table_" + getState(i).getIdent() + ".html";
- conditionally_write_file(path + filename, out);
- }
-
- // Generate action descriptions
- for(int i=0; i<numActions(); i++) {
- ostringstream out;
- createHTMLSymbol(getAction(i), "Action", out);
-
- // -- Write file
- filename = component + "_action_" + getAction(i).getIdent() + ".html";
- conditionally_write_file(path + filename, out);
- }
-
- // Generate state descriptions
- for(int i=0; i<numStates(); i++) {
- ostringstream out;
- createHTMLSymbol(getState(i), "State", out);
-
- // -- Write file
- filename = component + "_State_" + getState(i).getIdent() + ".html";
- conditionally_write_file(path + filename, out);
- }
-
- // Generate event descriptions
- for(int i=0; i<numEvents(); i++) {
- ostringstream out;
- createHTMLSymbol(getEvent(i), "Event", out);
-
- // -- Write file
- filename = component + "_Event_" + getEvent(i).getIdent() + ".html";
- conditionally_write_file(path + filename, out);
- }
-}
-
-void StateMachine::printHTMLTransitions(ostream& out, int active_state)
-{
- // -- Prolog
- out << "<HTML><BODY link=\"blue\" vlink=\"blue\">" << endl;
-
- // -- Header
- out << "<H1 align=\"center\">" << formatHTMLShorthand(getShorthand()) << ": " << endl;
- Vector<StateMachine*> machine_vec = g_sym_table.getStateMachines();
- for (int i=0; i<machine_vec.size(); i++) {
- StateMachine* type = machine_vec[i];
- if (i != 0) {
- out << " - ";
- }
- if (type == this) {
- out << type->getIdent() << endl;
- } else {
- out << "<A target=\"Table\"href=\"" + type->getIdent() + "_table.html\">" + type->getIdent() + "</A> " << endl;
- }
- }
- out << "</H1>" << endl;
-
- // -- Table header
- out << "<TABLE border=1>" << endl;
-
- // -- Column headers
- out << "<TR>" << endl;
-
- // -- First column header
- out << " <TH> </TH>" << endl;
-
- for(int event = 0; event < numEvents(); event++ ) {
- out << " <TH bgcolor=white>";
- out << frameRef(getIdent() + "_Event_" + getEvent(event).getIdent() + ".html", "Status", "1", formatHTMLShorthand(getEvent(event).getShorthand()));
- out << "</TH>" << endl;
- }
-
- out << "</TR>" << endl;
-
- // -- Body of table
- for(int state = 0; state < numStates(); state++ ) {
- out << "<TR>" << endl;
-
- // -- Each row
- if (state == active_state) {
- out << " <TH bgcolor=yellow>";
- } else {
- out << " <TH bgcolor=white>";
- }
-
- string click_href = getIdent() + "_table_" + getState(state).getIdent() + ".html";
- string text = formatHTMLShorthand(getState(state).getShorthand());
-
- out << frameRef(click_href, "Table", getIdent() + "_State_" + getState(state).getIdent() + ".html", "1", formatHTMLShorthand(getState(state).getShorthand()));
- out << "</TH>" << endl;
-
- // -- One column for each event
- for(int event = 0; event < numEvents(); event++ ) {
- const Transition* trans_ptr = getTransPtr(state, event);
-
- if( trans_ptr != NULL ) {
- bool stall_action = false;
- string nextState;
- string actions_str;
-
- // -- Get the actions
- // actions = trans_ptr->getActionShorthands();
- const Vector<Action*> actions = trans_ptr->getActions();
- for (int action=0; action < actions.size(); action++) {
- if ((actions[action]->getIdent() == "z_stall") ||
- (actions[action]->getIdent() == "zz_recycleMandatoryQueue")) {
- stall_action = true;
- }
- actions_str += " ";
- actions_str += frameRef(getIdent() + "_action_" + actions[action]->getIdent() + ".html", "Status", "1",
- formatHTMLShorthand(actions[action]->getShorthand()));
- actions_str += "\n";
- }
-
- // -- Get the next state
- if (trans_ptr->getNextStatePtr()->getIdent() != getState(state).getIdent()) {
- string click_href = getIdent() + "_table_" + trans_ptr->getNextStatePtr()->getIdent() + ".html";
- nextState = frameRef(click_href, "Table", getIdent() + "_State_" + trans_ptr->getNextStatePtr()->getIdent() + ".html", "1",
- formatHTMLShorthand(trans_ptr->getNextStateShorthand()));
- } else {
- nextState = "";
- }
-
- // -- Print out "actions/next-state"
- if (stall_action) {
- if (state == active_state) {
- out << " <TD bgcolor=#C0C000>";
- } else {
- out << " <TD bgcolor=lightgrey>";
- }
- } else if (active_state < numStates() && (trans_ptr->getNextStatePtr()->getIdent() == getState(active_state).getIdent())) {
- out << " <TD bgcolor=aqua>";
- } else if (state == active_state) {
- out << " <TD bgcolor=yellow>";
- } else {
- out << " <TD bgcolor=white>";
- }
-
- out << actions_str;
- if ((nextState.length() != 0) && (actions_str.length() != 0)) {
- out << "/";
- }
- out << nextState;
- out << "</TD>" << endl;
- } else {
- // This is the no transition case
- if (state == active_state) {
- out << " <TD bgcolor=#C0C000>&nbsp;</TD>" << endl;
- } else {
- out << " <TD bgcolor=lightgrey>&nbsp;</TD>" << endl;
- }
- }
- }
- // -- Each row
- if (state == active_state) {
- out << " <TH bgcolor=yellow>";
- } else {
- out << " <TH bgcolor=white>";
- }
-
- click_href = getIdent() + "_table_" + getState(state).getIdent() + ".html";
- text = formatHTMLShorthand(getState(state).getShorthand());
-
- out << frameRef(click_href, "Table", getIdent() + "_State_" + getState(state).getIdent() + ".html", "1", formatHTMLShorthand(getState(state).getShorthand()));
- out << "</TH>" << endl;
-
- out << "</TR>" << endl;
- }
-
- // -- Column footer
- out << "<TR>" << endl;
- out << " <TH> </TH>" << endl;
-
- for(int i = 0; i < numEvents(); i++ ) {
- out << " <TH bgcolor=white>";
- out << frameRef(getIdent() + "_Event_" + getEvent(i).getIdent() + ".html", "Status", "1", formatHTMLShorthand(getEvent(i).getShorthand()));
- out << "</TH>" << endl;
- }
- out << "</TR>" << endl;
-
- // -- Epilog
- out << "</TABLE>" << endl;
- out << "</BODY></HTML>" << endl;
-}
-
-
diff --git a/src/mem/slicc/symbols/StateMachine.hh b/src/mem/slicc/symbols/StateMachine.hh
deleted file mode 100644
index f5f3ab073..000000000
--- a/src/mem/slicc/symbols/StateMachine.hh
+++ /dev/null
@@ -1,156 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- *
- * */
-
-#ifndef STATEMACHINE_H
-#define STATEMACHINE_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/gems_common/Vector.hh"
-#include "mem/gems_common/Map.hh"
-#include "mem/slicc/symbols/Symbol.hh"
-#include <list>
-
-using namespace std;
-
-class Transition;
-class Event;
-class State;
-class Action;
-class Var;
-class Func;
-class FormalParamAST;
-
-class StateMachine : public Symbol {
-public:
- // Constructors
- StateMachine(string ident, const Location& location, const Map<string, string>& pairs, Vector<FormalParamAST*>* config_parameters);
-
- // Destructor
- ~StateMachine();
-
- // Public Methods
-
- // Add items to the state machine
- // void setMachine(string ident, const Map<string, string>& pairs);
- void addState(State* state_ptr);
- void addEvent(Event* event_ptr);
- void addAction(Action* action_ptr);
- void addTransition(Transition* trans_ptr);
- void addInPort(Var* var) { m_in_ports.insertAtBottom(var); }
- void addFunc(Func* func);
- void addObj(Var* obj) { m_objs.insertAtBottom(obj); }
-
- // Accessors to vectors
- const State& getState(int index) const { return *m_states[index]; }
- const Event& getEvent(int index) const { return *m_events[index]; }
- const Action& getAction(int index) const { return *m_actions[index]; }
- const Transition& getTransition(int index) const { return *m_transitions[index]; }
- const Transition* getTransPtr(int stateIndex, int eventIndex) const;
- const Var& getObject(int index) const { return *m_objs[index]; }
-
- // Accessors for size of vectors
- int numStates() const { return m_states.size(); }
- int numEvents() const { return m_events.size(); }
- int numActions() const { return m_actions.size(); }
- int numTransitions() const { return m_transitions.size(); }
- int numObjects() const { return m_objs.size(); }
-
- void buildTable(); // Needs to be called before accessing the table
-
- // Code generator methods
- void writeCFiles(string path) ;
- void writeHTMLFiles(string path) ;
-
- void print(ostream& out) const { out << "[StateMachine: " << toString() << "]" << endl; }
-private:
-
- Vector<FormalParamAST*>* m_config_parameters;
-
- // Private Methods
- void checkForDuplicate(const Symbol& sym) const;
-
- int getStateIndex(State* state_ptr) const { return m_state_map.lookup(state_ptr); }
- int getEventIndex(Event* event_ptr) const { return m_event_map.lookup(event_ptr); }
-
- // Private copy constructor and assignment operator
- // StateMachine(const StateMachine& obj);
- // StateMachine& operator=(const StateMachine& obj);
-
- void printControllerH(ostream& out, string component) ;
- void printControllerC(ostream& out, string component) ;
- void printCWakeup(ostream& out, string component) ;
- void printCSwitch(ostream& out, string component) ;
- void printProfilerH(ostream& out, string component) ;
- void printProfilerC(ostream& out, string component) ;
-
- void printHTMLTransitions(ostream& out, int active_state) ;
-
- // Data Members (m_ prefix)
- Vector<State*> m_states;
- Vector<Event*> m_events;
- Vector<Action*> m_actions;
- Vector<Transition*> m_transitions;
- Vector<Func*> m_internal_func_vec;
-
- Map<State*, int> m_state_map;
- Map<Event*, int> m_event_map;
-
- Vector<Var*> m_in_ports;
-
- Vector<Var*> m_objs;
-
- // Table variables
- bool m_table_built;
- Vector<Vector<Transition*> > m_table;
-
- //added by SS
- std::vector<std::string> m_message_buffer_names;
-
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const StateMachine& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const StateMachine& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //STATEMACHINE_H
diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py
new file mode 100644
index 000000000..af9850896
--- /dev/null
+++ b/src/mem/slicc/symbols/StateMachine.py
@@ -0,0 +1,1164 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.util import code_formatter, orderdict
+
+from slicc.symbols.Symbol import Symbol
+from slicc.symbols.Var import Var
+import slicc.generate.html as html
+
+class StateMachine(Symbol):
+ def __init__(self, symtab, ident, location, pairs, config_parameters):
+ super(StateMachine, self).__init__(symtab, ident, location, pairs)
+ self.table = None
+ self.config_parameters = config_parameters
+ for param in config_parameters:
+ var = Var(symtab, param.name, location, param.type_ast.type,
+ "m_%s" % param.name, {}, self)
+ self.symtab.registerSym(param.name, var)
+
+ self.states = orderdict()
+ self.events = orderdict()
+ self.actions = orderdict()
+ self.transitions = []
+ self.in_ports = []
+ self.functions = []
+ self.objects = []
+
+ self.message_buffer_names = []
+
+ def __repr__(self):
+ return "[StateMachine: %s]" % self.ident
+
+ def addState(self, state):
+ assert self.table is None
+ self.states[state.ident] = state
+
+ def addEvent(self, event):
+ assert self.table is None
+ self.events[event.ident] = event
+
+ def addAction(self, action):
+ assert self.table is None
+
+ # Check for duplicate action
+ for other in self.actions.itervalues():
+ if action.ident == other.ident:
+ action.warning("Duplicate action definition: %s" % action.ident)
+ action.error("Duplicate action definition: %s" % action.ident)
+ if action.short == other.short:
+ other.warning("Duplicate action shorthand: %s" % other.ident)
+ other.warning(" shorthand = %s" % other.short)
+ action.warning("Duplicate action shorthand: %s" % action.ident)
+ action.error(" shorthand = %s" % action.short)
+
+ self.actions[action.ident] = action
+
+ def addTransition(self, trans):
+ assert self.table is None
+ self.transitions.append(trans)
+
+ def addInPort(self, var):
+ self.in_ports.append(var)
+
+ def addFunc(self, func):
+ # register func in the symbol table
+ self.symtab.registerSym(str(func), func)
+ self.functions.append(func)
+
+ def addObject(self, obj):
+ self.objects.append(obj)
+
+ # Needs to be called before accessing the table
+ def buildTable(self):
+ assert self.table is None
+
+ table = {}
+
+ for trans in self.transitions:
+ # Track which actions we touch so we know if we use them
+ # all -- really this should be done for all symbols as
+ # part of the symbol table, then only trigger it for
+ # Actions, States, Events, etc.
+
+ for action in trans.actions:
+ action.used = True
+
+ index = (trans.state, trans.event)
+ if index in table:
+ table[index].warning("Duplicate transition: %s" % table[index])
+ trans.error("Duplicate transition: %s" % trans)
+ table[index] = trans
+
+ # Look at all actions to make sure we used them all
+ for action in self.actions.itervalues():
+ if not action.used:
+ error_msg = "Unused action: %s" % action.ident
+ if "desc" in action:
+ error_msg += ", " + action.desc
+ action.warning(error_msg)
+ self.table = table
+
+ def writeCodeFiles(self, path):
+ self.printControllerHH(path)
+ self.printControllerCC(path)
+ self.printCSwitch(path)
+ self.printCWakeup(path)
+ self.printProfilerCC(path)
+ self.printProfilerHH(path)
+
+ for func in self.functions:
+ func.writeCodeFiles(path)
+
+ def printControllerHH(self, path):
+ '''Output the method declarations for the class declaration'''
+ code = code_formatter()
+ ident = self.ident
+ c_ident = "%s_Controller" % self.ident
+
+ self.message_buffer_names = []
+
+ code('''
+/** \\file $ident.hh
+ *
+ * Auto generated C++ code started by $__file__:$__line__
+ * Created by slicc definition of Module "${{self.short}}"
+ */
+
+#ifndef ${ident}_CONTROLLER_H
+#define ${ident}_CONTROLLER_H
+
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/common/Consumer.hh"
+#include "mem/ruby/slicc_interface/AbstractController.hh"
+#include "mem/protocol/TransitionResult.hh"
+#include "mem/protocol/Types.hh"
+#include "mem/protocol/${ident}_Profiler.hh"
+''')
+
+ seen_types = set()
+ for var in self.objects:
+ if var.type.ident not in seen_types and not var.type.isPrimitive:
+ code('#include "mem/protocol/${{var.type.c_ident}}.hh"')
+ seen_types.add(var.type.ident)
+
+ # for adding information to the protocol debug trace
+ code('''
+extern stringstream ${ident}_transitionComment;
+
+class $c_ident : public AbstractController {
+#ifdef CHECK_COHERENCE
+#endif /* CHECK_COHERENCE */
+public:
+ $c_ident(const string & name);
+ static int getNumControllers();
+ void init(Network* net_ptr, const vector<string> & argv);
+ MessageBuffer* getMandatoryQueue() const;
+ const int & getVersion() const;
+ const string toString() const;
+ const string getName() const;
+ const MachineType getMachineType() const;
+ void print(ostream& out) const;
+ void printConfig(ostream& out) const;
+ void wakeup();
+ void set_atomic(Address addr);
+ void clear_atomic(Address addr);
+ void reset_atomics();
+ void printStats(ostream& out) const { s_profiler.dumpStats(out); }
+ void clearStats() { s_profiler.clearStats(); }
+private:
+''')
+
+ code.indent()
+ # added by SS
+ for param in self.config_parameters:
+ code('int m_${{param.ident}};')
+
+ if self.ident == "L1Cache":
+ code('''
+int servicing_atomic;
+Address locked_read_request1;
+Address locked_read_request2;
+Address locked_read_request3;
+Address locked_read_request4;
+int read_counter;
+''')
+
+ code('''
+int m_number_of_TBEs;
+
+TransitionResult doTransition(${ident}_Event event, ${ident}_State state, const Address& addr); // in ${ident}_Transitions.cc
+TransitionResult doTransitionWorker(${ident}_Event event, ${ident}_State state, ${ident}_State& next_state, const Address& addr); // in ${ident}_Transitions.cc
+string m_name;
+int m_transitions_per_cycle;
+int m_buffer_size;
+int m_recycle_latency;
+map< string, string > m_cfg;
+NodeID m_version;
+Network* m_net_ptr;
+MachineID m_machineID;
+${ident}_Profiler s_profiler;
+static int m_num_controllers;
+// Internal functions
+''')
+
+ for func in self.functions:
+ proto = func.prototype
+ if proto:
+ code('$proto')
+
+ code('''
+
+// Actions
+''')
+ for action in self.actions.itervalues():
+ code('/** \\brief ${{action.desc}} */')
+ code('void ${{action.ident}}(const Address& addr);')
+
+ # the controller internal variables
+ code('''
+
+// Object
+''')
+ for var in self.objects:
+ th = var.get("template_hack", "")
+ code('${{var.type.c_ident}}$th* m_${{var.c_ident}}_ptr;')
+
+ if var.type.ident == "MessageBuffer":
+ self.message_buffer_names.append("m_%s_ptr" % var.c_ident)
+
+ code.dedent()
+ code('};')
+ code('#endif // ${ident}_CONTROLLER_H')
+ code.write(path, '%s.hh' % c_ident)
+
+ def printControllerCC(self, path):
+ '''Output the actions for performing the actions'''
+
+ code = code_formatter()
+ ident = self.ident
+ c_ident = "%s_Controller" % self.ident
+
+ code('''
+/** \\file $ident.cc
+ *
+ * Auto generated C++ code started by $__file__:$__line__
+ * Created by slicc definition of Module "${{self.short}}"
+ */
+
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/slicc_interface/RubySlicc_includes.hh"
+#include "mem/protocol/${ident}_Controller.hh"
+#include "mem/protocol/${ident}_State.hh"
+#include "mem/protocol/${ident}_Event.hh"
+#include "mem/protocol/Types.hh"
+#include "mem/ruby/system/System.hh"
+''')
+
+ # include object classes
+ seen_types = set()
+ for var in self.objects:
+ if var.type.ident not in seen_types and not var.type.isPrimitive:
+ code('#include "mem/protocol/${{var.type.c_ident}}.hh"')
+ seen_types.add(var.type.ident)
+
+ code('''
+int $c_ident::m_num_controllers = 0;
+
+stringstream ${ident}_transitionComment;
+#define APPEND_TRANSITION_COMMENT(str) (${ident}_transitionComment << str)
+/** \\brief constructor */
+$c_ident::$c_ident(const string &name)
+ : m_name(name)
+{
+''')
+ code.indent()
+ if self.ident == "L1Cache":
+ code('''
+servicing_atomic = 0;
+locked_read_request1 = Address(-1);
+locked_read_request2 = Address(-1);
+locked_read_request3 = Address(-1);
+locked_read_request4 = Address(-1);
+read_counter = 0;
+''')
+
+ code('m_num_controllers++;')
+ for var in self.objects:
+ if var.ident.find("mandatoryQueue") >= 0:
+ code('m_${{var.c_ident}}_ptr = new ${{var.type.c_ident}}();')
+
+ code.dedent()
+ code('''
+}
+
+void $c_ident::init(Network *net_ptr, const vector<string> &argv)
+{
+ for (size_t i = 0; i < argv.size(); i += 2) {
+ if (argv[i] == "version")
+ m_version = atoi(argv[i+1].c_str());
+ else if (argv[i] == "transitions_per_cycle")
+ m_transitions_per_cycle = atoi(argv[i+1].c_str());
+ else if (argv[i] == "buffer_size")
+ m_buffer_size = atoi(argv[i+1].c_str());
+ else if (argv[i] == "recycle_latency")
+ m_recycle_latency = atoi(argv[i+1].c_str());
+ else if (argv[i] == "number_of_TBEs")
+ m_number_of_TBEs = atoi(argv[i+1].c_str());
+''')
+
+ code.indent()
+ code.indent()
+ for param in self.config_parameters:
+ code('else if (argv[i] == "${{param.name}}")')
+ if param.type_ast.type.ident == "int":
+ code(' m_${{param.name}} = atoi(argv[i+1].c_str());')
+ elif param.type_ast.type.ident == "bool":
+ code(' m_${{param.name}} = string_to_bool(argv[i+1]);')
+ else:
+ self.error("only int and bool parameters are "\
+ "currently supported")
+ code.dedent()
+ code.dedent()
+ code('''
+ }
+
+ m_net_ptr = net_ptr;
+ m_machineID.type = MachineType_${ident};
+ m_machineID.num = m_version;
+ for (size_t i = 0; i < argv.size(); i += 2) {
+ if (argv[i] != "version")
+ m_cfg[argv[i]] = argv[i+1];
+ }
+
+ // Objects
+ s_profiler.setVersion(m_version);
+''')
+
+ code.indent()
+ for var in self.objects:
+ vtype = var.type
+ vid = "m_%s_ptr" % var.c_ident
+ if "network" not in var:
+ # Not a network port object
+ if "primitive" in vtype:
+ code('$vid = new ${{vtype.c_ident}};')
+ if "default" in var:
+ code('(*$vid) = ${{var["default"]}};')
+ else:
+ # Normal Object
+ # added by SS
+ if "factory" in var:
+ code('$vid = ${{var["factory"]}};')
+ elif var.ident.find("mandatoryQueue") < 0:
+ th = var.get("template_hack", "")
+ expr = "%s = new %s%s" % (vid, vtype.c_ident, th)
+
+ args = ""
+ if "non_obj" not in vtype and not vtype.isEnumeration:
+ if expr.find("TBETable") >= 0:
+ args = "m_number_of_TBEs"
+ else:
+ args = var.get("constructor_hack", "")
+ args = "(%s)" % args
+
+ code('$expr$args;')
+ else:
+ code(';')
+
+ code('assert($vid != NULL);')
+
+ if "default" in var:
+ code('(*$vid) = ${{var["default"]}}; // Object default')
+ elif "default" in vtype:
+ code('(*$vid) = ${{vtype["default"]}}; // Type ${{vtype.ident}} default')
+
+ # Set ordering
+ if "ordered" in var and "trigger_queue" not in var:
+ # A buffer
+ code('$vid->setOrdering(${{var["ordered"]}});')
+
+ # Set randomization
+ if "random" in var:
+ # A buffer
+ code('$vid->setRandomization(${{var["random"]}});')
+
+ # Set Priority
+ if vtype.isBuffer and \
+ "rank" in var and "trigger_queue" not in var:
+ code('$vid->setPriority(${{var["rank"]}});')
+ else:
+ # Network port object
+ network = var["network"]
+ ordered = var["ordered"]
+ vnet = var["virtual_network"]
+
+ assert var.machine is not None
+ code('''
+$vid = m_net_ptr->get${network}NetQueue(m_version+MachineType_base_number(string_to_MachineType("${{var.machine.ident}}")), $ordered, $vnet);
+''')
+
+ code('assert($vid != NULL);')
+
+ # Set ordering
+ if "ordered" in var:
+ # A buffer
+ code('$vid->setOrdering(${{var["ordered"]}});')
+
+ # Set randomization
+ if "random" in var:
+ # A buffer
+ code('$vid->setRandomization(${{var["random"]}})')
+
+ # Set Priority
+ if "rank" in var:
+ code('$vid->setPriority(${{var["rank"]}})')
+
+ # Set buffer size
+ if vtype.isBuffer:
+ code('''
+if (m_buffer_size > 0) {
+ $vid->setSize(m_buffer_size);
+}
+''')
+
+ # set description (may be overriden later by port def)
+ code('$vid->setDescription("[Version " + int_to_string(m_version) + ", ${ident}, name=${{var.c_ident}}]");')
+
+ # Set the queue consumers
+ code.insert_newline()
+ for port in self.in_ports:
+ code('${{port.code}}.setConsumer(this);')
+
+ # Set the queue descriptions
+ code.insert_newline()
+ for port in self.in_ports:
+ code('${{port.code}}.setDescription("[Version " + int_to_string(m_version) + ", $ident, $port]");')
+
+ # Initialize the transition profiling
+ code.insert_newline()
+ for trans in self.transitions:
+ # Figure out if we stall
+ stall = False
+ for action in trans.actions:
+ if action.ident == "z_stall":
+ stall = True
+
+ # Only possible if it is not a 'z' case
+ if not stall:
+ state = "%s_State_%s" % (self.ident, trans.state.ident)
+ event = "%s_Event_%s" % (self.ident, trans.event.ident)
+ code('s_profiler.possibleTransition($state, $event);')
+
+ # added by SS to initialize recycle_latency of message buffers
+ for buf in self.message_buffer_names:
+ code("$buf->setRecycleLatency(m_recycle_latency);")
+
+ code.dedent()
+ code('}')
+
+ has_mandatory_q = False
+ for port in self.in_ports:
+ if port.code.find("mandatoryQueue_ptr") >= 0:
+ has_mandatory_q = True
+
+ if has_mandatory_q:
+ mq_ident = "m_%s_mandatoryQueue_ptr" % self.ident
+ else:
+ mq_ident = "NULL"
+
+ code('''
+int $c_ident::getNumControllers() {
+ return m_num_controllers;
+}
+
+MessageBuffer* $c_ident::getMandatoryQueue() const {
+ return $mq_ident;
+}
+
+const int & $c_ident::getVersion() const{
+ return m_version;
+}
+
+const string $c_ident::toString() const{
+ return "$c_ident";
+}
+
+const string $c_ident::getName() const{
+ return m_name;
+}
+const MachineType $c_ident::getMachineType() const{
+ return MachineType_${ident};
+}
+
+void $c_ident::print(ostream& out) const { out << "[$c_ident " << m_version << "]"; }
+
+void $c_ident::printConfig(ostream& out) const {
+ out << "$c_ident config: " << m_name << endl;
+ out << " version: " << m_version << endl;
+ for (map<string, string>::const_iterator it = m_cfg.begin(); it != m_cfg.end(); it++) {
+ out << " " << (*it).first << ": " << (*it).second << endl;
+ }
+}
+
+// Actions
+''')
+
+ for action in self.actions.itervalues():
+ if "c_code" not in action:
+ continue
+
+ code('''
+/** \\brief ${{action.desc}} */
+void $c_ident::${{action.ident}}(const Address& addr)
+{
+ DEBUG_MSG(GENERATED_COMP, HighPrio, "executing");
+ ${{action["c_code"]}}
+}
+
+''')
+ code.write(path, "%s.cc" % c_ident)
+
+ def printCWakeup(self, path):
+ '''Output the wakeup loop for the events'''
+
+ code = code_formatter()
+ ident = self.ident
+
+ code('''
+// Auto generated C++ code started by $__file__:$__line__
+// ${ident}: ${{self.short}}
+
+#include "mem/ruby/common/Global.hh"
+#include "mem/ruby/slicc_interface/RubySlicc_includes.hh"
+#include "mem/protocol/${ident}_Controller.hh"
+#include "mem/protocol/${ident}_State.hh"
+#include "mem/protocol/${ident}_Event.hh"
+#include "mem/protocol/Types.hh"
+#include "mem/ruby/system/System.hh"
+
+void ${ident}_Controller::wakeup()
+{
+
+ int counter = 0;
+ while (true) {
+ // Some cases will put us into an infinite loop without this limit
+ assert(counter <= m_transitions_per_cycle);
+ if (counter == m_transitions_per_cycle) {
+ g_system_ptr->getProfiler()->controllerBusy(m_machineID); // Count how often we\'re fully utilized
+ g_eventQueue_ptr->scheduleEvent(this, 1); // Wakeup in another cycle and try again
+ break;
+ }
+''')
+
+ code.indent()
+ code.indent()
+
+ # InPorts
+ #
+ # Find the position of the mandatory queue in the vector so
+ # that we can print it out first
+
+ mandatory_q = None
+ if self.ident == "L1Cache":
+ for i,port in enumerate(self.in_ports):
+ assert "c_code_in_port" in port
+ if str(port).find("mandatoryQueue_in") >= 0:
+ assert mandatory_q is None
+ mandatory_q = port
+
+ assert mandatory_q is not None
+
+ # print out the mandatory queue here
+ port = mandatory_q
+ code('// ${ident}InPort $port')
+ output = port["c_code_in_port"]
+
+ code('$output')
+
+ for port in self.in_ports:
+ # don't print out mandatory queue twice
+ if port == mandatory_q:
+ continue
+
+ if ident == "L1Cache":
+ if (str(port).find("forwardRequestNetwork_in") >= 0 or str(port).find("requestNetwork_in") >= 0 or str(port).find("requestIntraChipL1Network_in") >= 0):
+ code('''
+bool postpone = false;
+if ((((*m_L1Cache_forwardToCache_ptr)).isReady())) {
+ const RequestMsg* in_msg_ptr;
+ in_msg_ptr = dynamic_cast<const RequestMsg*>(((*m_L1Cache_forwardToCache_ptr)).peek());
+ if ((((servicing_atomic > 0) && (locked_read_request1 == ((*in_msg_ptr)).m_Address || locked_read_request2 == ((*in_msg_ptr)).m_Address || locked_read_request3 == ((*in_msg_ptr)).m_Address || locked_read_request1 == ((*in_msg_ptr)).m_Address)))) {
+ postpone = true;
+ }
+}
+if (!postpone) {
+''')
+ code.indent()
+ code('// ${ident}InPort $port')
+ code('${{port["c_code_in_port"]}}')
+ code.dedent()
+
+ if ident == "L1Cache":
+ if (str(port).find("forwardRequestNetwork_in") >= 0 or str(port).find("requestNetwork_in") >= 0 or str(port).find("requestIntraChipL1Network_in") >= 0):
+ code.dedent()
+ code('}')
+ code.indent()
+ code('')
+
+ code.dedent()
+ code.dedent()
+ code('''
+ break; // If we got this far, we have nothing left todo
+ }
+}
+''')
+
+ if self.ident == "L1Cache":
+ code('''
+void ${ident}_Controller::set_atomic(Address addr)
+{
+ servicing_atomic++;
+ switch (servicing_atomic) {
+ case(1):
+ assert(locked_read_request1 == Address(-1));
+ locked_read_request1 = addr;
+ break;
+ case(2):
+ assert(locked_read_request2 == Address(-1));
+ locked_read_request2 = addr;
+ break;
+ case(3):
+ assert(locked_read_request3 == Address(-1));
+ locked_read_request3 = addr;
+ break;
+ case(4):
+ assert(locked_read_request4 == Address(-1));
+ locked_read_request4 = addr;
+ break;
+ default:
+ assert(0);
+
+ }
+}
+
+void ${ident}_Controller::clear_atomic(Address addr)
+{
+
+ assert(servicing_atomic > 0);
+ if (addr == locked_read_request1)
+ locked_read_request1 = Address(-1);
+ else if (addr == locked_read_request2)
+ locked_read_request2 = Address(-1);
+ else if (addr == locked_read_request3)
+ locked_read_request3 = Address(-1);
+ else if (addr == locked_read_request4)
+ locked_read_request4 = Address(-1);
+ else
+ assert(0);
+ servicing_atomic--;
+
+}
+
+void ${ident}_Controller::reset_atomics()
+{
+
+ servicing_atomic = 0;
+ locked_read_request1 = Address(-1);
+ locked_read_request2 = Address(-1);
+ locked_read_request3 = Address(-1);
+ locked_read_request4 = Address(-1);
+
+}
+
+''')
+ else:
+ code('''
+void ${ident}_Controller::reset_atomics()
+{
+ assert(0);
+}
+
+void ${ident}_Controller::set_atomic(Address addr)
+{
+ assert(0);
+}
+
+void ${ident}_Controller::clear_atomic(Address addr)
+{
+ assert(0);
+}
+''')
+
+
+ code.write(path, "%s_Wakeup.cc" % self.ident)
+
+ def printCSwitch(self, path):
+ '''Output switch statement for transition table'''
+
+ code = code_formatter()
+ ident = self.ident
+
+ code('''
+// Auto generated C++ code started by $__file__:$__line__
+// ${ident}: ${{self.short}}
+
+#include "mem/ruby/common/Global.hh"
+#include "mem/protocol/${ident}_Controller.hh"
+#include "mem/protocol/${ident}_State.hh"
+#include "mem/protocol/${ident}_Event.hh"
+#include "mem/protocol/Types.hh"
+#include "mem/ruby/system/System.hh"
+
+#define HASH_FUN(state, event) ((int(state)*${ident}_Event_NUM)+int(event))
+
+#define GET_TRANSITION_COMMENT() (${ident}_transitionComment.str())
+#define CLEAR_TRANSITION_COMMENT() (${ident}_transitionComment.str(""))
+
+TransitionResult ${ident}_Controller::doTransition(${ident}_Event event, ${ident}_State state, const Address& addr
+)
+{
+ ${ident}_State next_state = state;
+
+ DEBUG_NEWLINE(GENERATED_COMP, MedPrio);
+ DEBUG_MSG(GENERATED_COMP, MedPrio, *this);
+ DEBUG_EXPR(GENERATED_COMP, MedPrio, g_eventQueue_ptr->getTime());
+ DEBUG_EXPR(GENERATED_COMP, MedPrio,state);
+ DEBUG_EXPR(GENERATED_COMP, MedPrio,event);
+ DEBUG_EXPR(GENERATED_COMP, MedPrio,addr);
+
+ TransitionResult result = doTransitionWorker(event, state, next_state, addr);
+
+ if (result == TransitionResult_Valid) {
+ DEBUG_EXPR(GENERATED_COMP, MedPrio, next_state);
+ DEBUG_NEWLINE(GENERATED_COMP, MedPrio);
+ s_profiler.countTransition(state, event);
+ if (Debug::getProtocolTrace()) {
+ g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr,
+ ${ident}_State_to_string(state),
+ ${ident}_Event_to_string(event),
+ ${ident}_State_to_string(next_state), GET_TRANSITION_COMMENT());
+ }
+ CLEAR_TRANSITION_COMMENT();
+ ${ident}_setState(addr, next_state);
+
+ } else if (result == TransitionResult_ResourceStall) {
+ if (Debug::getProtocolTrace()) {
+ g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr,
+ ${ident}_State_to_string(state),
+ ${ident}_Event_to_string(event),
+ ${ident}_State_to_string(next_state),
+ "Resource Stall");
+ }
+ } else if (result == TransitionResult_ProtocolStall) {
+ DEBUG_MSG(GENERATED_COMP, HighPrio, "stalling");
+ DEBUG_NEWLINE(GENERATED_COMP, MedPrio);
+ if (Debug::getProtocolTrace()) {
+ g_system_ptr->getProfiler()->profileTransition("${ident}", m_version, addr,
+ ${ident}_State_to_string(state),
+ ${ident}_Event_to_string(event),
+ ${ident}_State_to_string(next_state),
+ "Protocol Stall");
+ }
+ }
+
+ return result;
+}
+
+TransitionResult ${ident}_Controller::doTransitionWorker(${ident}_Event event, ${ident}_State state, ${ident}_State& next_state, const Address& addr
+)
+{
+ switch(HASH_FUN(state, event)) {
+''')
+
+ # This map will allow suppress generating duplicate code
+ cases = orderdict()
+
+ for trans in self.transitions:
+ case_string = "%s_State_%s, %s_Event_%s" % \
+ (self.ident, trans.state.ident, self.ident, trans.event.ident)
+
+ case = code_formatter()
+ # Only set next_state if it changes
+ if trans.state != trans.nextState:
+ ns_ident = trans.nextState.ident
+ case('next_state = ${ident}_State_${ns_ident};')
+
+ actions = trans.actions
+
+ # Check for resources
+ case_sorter = []
+ res = trans.resources
+ for key,val in res.iteritems():
+ if key.type.ident != "DNUCAStopTable":
+ val = '''
+if (!%s.areNSlotsAvailable(%s)) {
+ return TransitionResult_ResourceStall;
+}
+''' % (key.code, val)
+ case_sorter.append(val)
+
+
+ # Emit the code sequences in a sorted order. This makes the
+ # output deterministic (without this the output order can vary
+ # since Map's keys() on a vector of pointers is not deterministic
+ for c in sorted(case_sorter):
+ case("$c")
+
+ # Figure out if we stall
+ stall = False
+ for action in actions:
+ if action.ident == "z_stall":
+ stall = True
+ break
+
+ if stall:
+ case('return TransitionResult_ProtocolStall;')
+ else:
+ for action in actions:
+ case('${{action.ident}}(addr);')
+ case('return TransitionResult_Valid;')
+
+ case = str(case)
+
+ # Look to see if this transition code is unique.
+ if case not in cases:
+ cases[case] = []
+
+ cases[case].append(case_string)
+
+ # Walk through all of the unique code blocks and spit out the
+ # corresponding case statement elements
+ for case,transitions in cases.iteritems():
+ # Iterative over all the multiple transitions that share
+ # the same code
+ for trans in transitions:
+ code(' case HASH_FUN($trans):')
+ code(' {')
+ code(' $case')
+ code(' }')
+
+ code('''
+ default:
+ WARN_EXPR(m_version);
+ WARN_EXPR(g_eventQueue_ptr->getTime());
+ WARN_EXPR(addr);
+ WARN_EXPR(event);
+ WARN_EXPR(state);
+ ERROR_MSG(\"Invalid transition\");
+ }
+ return TransitionResult_Valid;
+}
+''')
+ code.write(path, "%s_Transitions.cc" % self.ident)
+
+ def printProfilerHH(self, path):
+ code = code_formatter()
+ ident = self.ident
+
+ code('''
+// Auto generated C++ code started by $__file__:$__line__
+// ${ident}: ${{self.short}}
+
+#ifndef ${ident}_PROFILER_H
+#define ${ident}_PROFILER_H
+
+#include "mem/ruby/common/Global.hh"
+#include "mem/protocol/${ident}_State.hh"
+#include "mem/protocol/${ident}_Event.hh"
+
+class ${ident}_Profiler {
+ public:
+ ${ident}_Profiler();
+ void setVersion(int version);
+ void countTransition(${ident}_State state, ${ident}_Event event);
+ void possibleTransition(${ident}_State state, ${ident}_Event event);
+ void dumpStats(ostream& out) const;
+ void clearStats();
+
+ private:
+ int m_counters[${ident}_State_NUM][${ident}_Event_NUM];
+ int m_event_counters[${ident}_Event_NUM];
+ bool m_possible[${ident}_State_NUM][${ident}_Event_NUM];
+ int m_version;
+};
+
+#endif // ${ident}_PROFILER_H
+''')
+ code.write(path, "%s_Profiler.hh" % self.ident)
+
+ def printProfilerCC(self, path):
+ code = code_formatter()
+ ident = self.ident
+
+ code('''
+// Auto generated C++ code started by $__file__:$__line__
+// ${ident}: ${{self.short}}
+
+#include "mem/protocol/${ident}_Profiler.hh"
+
+${ident}_Profiler::${ident}_Profiler()
+{
+ for (int state = 0; state < ${ident}_State_NUM; state++) {
+ for (int event = 0; event < ${ident}_Event_NUM; event++) {
+ m_possible[state][event] = false;
+ m_counters[state][event] = 0;
+ }
+ }
+ for (int event = 0; event < ${ident}_Event_NUM; event++) {
+ m_event_counters[event] = 0;
+ }
+}
+void ${ident}_Profiler::setVersion(int version)
+{
+ m_version = version;
+}
+void ${ident}_Profiler::clearStats()
+{
+ for (int state = 0; state < ${ident}_State_NUM; state++) {
+ for (int event = 0; event < ${ident}_Event_NUM; event++) {
+ m_counters[state][event] = 0;
+ }
+ }
+
+ for (int event = 0; event < ${ident}_Event_NUM; event++) {
+ m_event_counters[event] = 0;
+ }
+}
+void ${ident}_Profiler::countTransition(${ident}_State state, ${ident}_Event event)
+{
+ assert(m_possible[state][event]);
+ m_counters[state][event]++;
+ m_event_counters[event]++;
+}
+void ${ident}_Profiler::possibleTransition(${ident}_State state, ${ident}_Event event)
+{
+ m_possible[state][event] = true;
+}
+void ${ident}_Profiler::dumpStats(ostream& out) const
+{
+ out << " --- ${ident} " << m_version << " ---" << endl;
+ out << " - Event Counts -" << endl;
+ for (int event = 0; event < ${ident}_Event_NUM; event++) {
+ int count = m_event_counters[event];
+ out << (${ident}_Event) event << " " << count << endl;
+ }
+ out << endl;
+ out << " - Transitions -" << endl;
+ for (int state = 0; state < ${ident}_State_NUM; state++) {
+ for (int event = 0; event < ${ident}_Event_NUM; event++) {
+ if (m_possible[state][event]) {
+ int count = m_counters[state][event];
+ out << (${ident}_State) state << " " << (${ident}_Event) event << " " << count;
+ if (count == 0) {
+ out << " <-- ";
+ }
+ out << endl;
+ }
+ }
+ out << endl;
+ }
+}
+''')
+ code.write(path, "%s_Profiler.cc" % self.ident)
+
+ # **************************
+ # ******* HTML Files *******
+ # **************************
+ def frameRef(self, click_href, click_target, over_href, over_target_num,
+ text):
+ code = code_formatter(fix_newlines=False)
+ code("""<A href=\"$click_href\" target=\"$click_target\" onMouseOver=\"if (parent.frames[$over_target_num].location != parent.location + '$over_href') { parent.frames[$over_target_num].location='$over_href' }\" >${{html.formatShorthand(text)}}</A>""")
+ return str(code)
+
+ def writeHTMLFiles(self, path):
+ # Create table with no row hilighted
+ self.printHTMLTransitions(path, None)
+
+ # Generate transition tables
+ for state in self.states.itervalues():
+ self.printHTMLTransitions(path, state)
+
+ # Generate action descriptions
+ for action in self.actions.itervalues():
+ name = "%s_action_%s.html" % (self.ident, action.ident)
+ code = html.createSymbol(action, "Action")
+ code.write(path, name)
+
+ # Generate state descriptions
+ for state in self.states.itervalues():
+ name = "%s_State_%s.html" % (self.ident, state.ident)
+ code = html.createSymbol(state, "State")
+ code.write(path, name)
+
+ # Generate event descriptions
+ for event in self.events.itervalues():
+ name = "%s_Event_%s.html" % (self.ident, event.ident)
+ code = html.createSymbol(event, "Event")
+ code.write(path, name)
+
+ def printHTMLTransitions(self, path, active_state):
+ code = code_formatter()
+
+ code('''
+<HTML><BODY link="blue" vlink="blue">
+
+<H1 align="center">${{html.formatShorthand(self.short)}}:
+''')
+ code.indent()
+ for i,machine in enumerate(self.symtab.getAllType(StateMachine)):
+ mid = machine.ident
+ if i != 0:
+ extra = " - "
+ else:
+ extra = ""
+ if machine == self:
+ code('$extra$mid')
+ else:
+ code('$extra<A target="Table" href="${mid}_table.html">$mid</A>')
+ code.dedent()
+
+ code("""
+</H1>
+
+<TABLE border=1>
+<TR>
+ <TH> </TH>
+""")
+
+ for event in self.events.itervalues():
+ href = "%s_Event_%s.html" % (self.ident, event.ident)
+ ref = self.frameRef(href, "Status", href, "1", event.short)
+ code('<TH bgcolor=white>$ref</TH>')
+
+ code('</TR>')
+ # -- Body of table
+ for state in self.states.itervalues():
+ # -- Each row
+ if state == active_state:
+ color = "yellow"
+ else:
+ color = "white"
+
+ click = "%s_table_%s.html" % (self.ident, state.ident)
+ over = "%s_State_%s.html" % (self.ident, state.ident)
+ text = html.formatShorthand(state.short)
+ ref = self.frameRef(click, "Table", over, "1", state.short)
+ code('''
+<TR>
+ <TH bgcolor=$color>$ref</TH>
+''')
+
+ # -- One column for each event
+ for event in self.events.itervalues():
+ trans = self.table.get((state,event), None)
+ if trans is None:
+ # This is the no transition case
+ if state == active_state:
+ color = "#C0C000"
+ else:
+ color = "lightgrey"
+
+ code('<TD bgcolor=$color>&nbsp;</TD>')
+ continue
+
+ next = trans.nextState
+ stall_action = False
+
+ # -- Get the actions
+ for action in trans.actions:
+ if action.ident == "z_stall" or \
+ action.ident == "zz_recycleMandatoryQueue":
+ stall_action = True
+
+ # -- Print out "actions/next-state"
+ if stall_action:
+ if state == active_state:
+ color = "#C0C000"
+ else:
+ color = "lightgrey"
+
+ elif active_state and next.ident == active_state.ident:
+ color = "aqua"
+ elif state == active_state:
+ color = "yellow"
+ else:
+ color = "white"
+
+ fix = code.nofix()
+ code('<TD bgcolor=$color>')
+ for action in trans.actions:
+ href = "%s_action_%s.html" % (self.ident, action.ident)
+ ref = self.frameRef(href, "Status", href, "1",
+ action.short)
+ code(' $ref\n')
+ if next != state:
+ if trans.actions:
+ code('/')
+ click = "%s_table_%s.html" % (self.ident, next.ident)
+ over = "%s_State_%s.html" % (self.ident, next.ident)
+ ref = self.frameRef(click, "Table", over, "1", next.short)
+ code("$ref")
+ code("</TD>\n")
+ code.fix(fix)
+
+ # -- Each row
+ if state == active_state:
+ color = "yellow"
+ else:
+ color = "white"
+
+ click = "%s_table_%s.html" % (self.ident, state.ident)
+ over = "%s_State_%s.html" % (self.ident, state.ident)
+ ref = self.frameRef(click, "Table", over, "1", state.short)
+ code('''
+ <TH bgcolor=$color>$ref</TH>
+</TR>
+''')
+ code('''
+<TR>
+ <TH> </TH>
+''')
+
+ for event in self.events.itervalues():
+ href = "%s_Event_%s.html" % (self.ident, event.ident)
+ ref = self.frameRef(href, "Status", href, "1", event.short)
+ code('<TH bgcolor=white>$ref</TH>')
+ code('''
+</TR>
+</TABLE>
+</BODY></HTML>
+''')
+
+
+ if active_state:
+ name = "%s_table_%s.html" % (self.ident, active_state.ident)
+ else:
+ name = "%s_table.html" % self.ident
+ code.write(path, name)
+
+__all__ = [ "StateMachine" ]
diff --git a/src/mem/slicc/symbols/Symbol.hh b/src/mem/slicc/symbols/Symbol.hh
deleted file mode 100644
index 4a1c5e44e..000000000
--- a/src/mem/slicc/symbols/Symbol.hh
+++ /dev/null
@@ -1,100 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- */
-
-#ifndef SYMBOL_H
-#define SYMBOL_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/gems_common/Map.hh"
-#include "mem/slicc/ast/Location.hh"
-
-class Symbol {
-public:
- // Constructors
- Symbol(string id, const Location& location, const Map<string, string>& pairs);
- Symbol(string id, const Location& location);
- // Destructor
- virtual ~Symbol() { }
-
- // Public Methods
- void error(string err_msg) const { m_location.error(err_msg); }
- void warning(string err_msg) const { m_location.warning(err_msg); }
- const Location& getLocation() const { return m_location; }
-
- const string& toString() const { return m_id; }
-
- const string& getIdent() const { return m_id; }
- const string& getShorthand() const { return lookupPair("short"); }
- const string& getDescription() const { return lookupPair("desc"); }
-
- void markUsed() { m_used = true; }
- bool wasUsed() { return m_used; }
-
- bool existPair(const string& key) const { return m_pairs.exist(key); }
- const string& lookupPair(const string& key) const;
- void addPair(const string& key, const string& value);
-
- // virtual string getCode() const = 0;
- virtual void writeCFiles(string path) {}
- virtual void writeHTMLFiles(string path) {}
- virtual void print(ostream& out) const { out << "[Symbol: " << getIdent() << "]"; }
-
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- // Symbol(const Symbol& obj);
- // Symbol& operator=(const Symbol& obj);
-
- // Data Members (m_ prefix)
- string m_id;
- Map<string, string> m_pairs;
- Location m_location;
- bool m_used;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const Symbol& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const Symbol& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //SYMBOL_H
diff --git a/src/mem/slicc/symbols/Symbol.py b/src/mem/slicc/symbols/Symbol.py
new file mode 100644
index 000000000..b394fda44
--- /dev/null
+++ b/src/mem/slicc/symbols/Symbol.py
@@ -0,0 +1,78 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.util import PairContainer
+
+class Symbol(PairContainer):
+ def __init__(self, symtab, ident, location, pairs=None):
+ super(Symbol, self).__init__()
+
+ from slicc.util import Location
+ from slicc.symbols import SymbolTable
+ if not isinstance(symtab, SymbolTable): raise AttributeError
+ if not isinstance(ident, str): raise AttributeError
+ if not isinstance(location, Location): raise AttributeError
+
+ self.symtab = symtab
+ self.ident = ident
+ self.location = location
+ if pairs:
+ self.pairs.update(getattr(pairs, "pairs", pairs))
+ if "short" not in self:
+ self["short"] = self.ident
+ self.used = False
+
+ def __repr__(self):
+ return "[Symbol: %s]" % self.ident
+
+ def __str__(self):
+ return str(self.ident)
+
+ def __setitem__(self, key, value):
+ if key in self.pairs:
+ self.warning("Pair key '%s' re-defined. new: '%s' old: '%s'",
+ key, value, self.pairs[key])
+ super(Symbol, self).__setitem__(key, value)
+
+ @property
+ def short(self):
+ return self["short"]
+
+ @property
+ def desc(self):
+ return self["desc"]
+
+ def error(self, message, *args):
+ self.location.error(message, *args)
+
+ def warning(self, message, *args):
+ self.location.warning(message, *args)
+
+ def writeHTMLFiles(self, path):
+ pass
+
+__all__ = [ "Symbol" ]
diff --git a/src/mem/slicc/symbols/SymbolTable.cc b/src/mem/slicc/symbols/SymbolTable.cc
deleted file mode 100644
index 8af3685f8..000000000
--- a/src/mem/slicc/symbols/SymbolTable.cc
+++ /dev/null
@@ -1,327 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * SymbolTable.cc
- *
- * Description: See SymbolTable.hh
- *
- * $Id$
- *
- * */
-
-#include "mem/slicc/symbols/SymbolTable.hh"
-#include "mem/slicc/generator/fileio.hh"
-#include "mem/slicc/generator/html_gen.hh"
-#include "mem/slicc/generator/mif_gen.hh"
-#include "mem/slicc/symbols/Action.hh"
-
-SymbolTable g_sym_table;
-
-SymbolTable::SymbolTable()
-{
- m_sym_map_vec.setSize(1);
- m_depth = 0;
-
- {
- Map<string, string> pairs;
- pairs.add("enumeration", "yes");
- newSym(new Type("MachineType", Location(), pairs));
- }
-
- {
- Map<string, string> pairs;
- pairs.add("primitive", "yes");
- pairs.add("external", "yes");
- newSym(new Type("void", Location(), pairs));
- }
-}
-
-SymbolTable::~SymbolTable()
-{
- int size = m_sym_vec.size();
- for(int i=0; i<size; i++) {
- delete m_sym_vec[i];
- }
-}
-
-void SymbolTable::newSym(Symbol* sym_ptr)
-{
- registerSym(sym_ptr->toString(), sym_ptr);
- m_sym_vec.insertAtBottom(sym_ptr); // Holder for the allocated Sym objects.
-}
-
-void SymbolTable::newMachComponentSym(Symbol* sym_ptr)
-{
- // used to cheat-- that is, access components in other machines
- StateMachine* mach_ptr = getStateMachine("current_machine");
- if (mach_ptr != NULL) {
- m_machine_component_map_vec.lookup(mach_ptr->toString()).add(sym_ptr->toString(), sym_ptr);
- }
-}
-
-Var* SymbolTable::getMachComponentVar(string mach, string ident)
-{
- Symbol* s = m_machine_component_map_vec.lookup(mach).lookup(ident);
- return dynamic_cast<Var*>(s);
-}
-
-
-void SymbolTable::registerSym(string id, Symbol* sym_ptr)
-{
-
- // Check for redeclaration (in the current frame only)
- if (m_sym_map_vec[m_depth].exist(id)) {
- sym_ptr->error("Symbol '" + id + "' redeclared in same scope.");
- }
- // FIXME - warn on masking of a declaration in a previous frame
- m_sym_map_vec[m_depth].add(id, sym_ptr);
-}
-
-void SymbolTable::registerGlobalSym(string id, Symbol* sym_ptr)
-{
- // Check for redeclaration (global frame only)
- if (m_sym_map_vec[0].exist(id)) {
- sym_ptr->error("Global symbol '" + id + "' redeclared in global scope.");
- }
- m_sym_map_vec[0].add(id, sym_ptr);
-}
-
-Symbol* SymbolTable::getSym(string ident) const
-{
- for (int i=m_depth; i>=0; i--) {
- if (m_sym_map_vec[i].exist(ident)) {
- return m_sym_map_vec[i].lookup(ident);
- }
- }
- return NULL;
-}
-
-void SymbolTable::newCurrentMachine(StateMachine* sym_ptr)
-{
- registerGlobalSym(sym_ptr->toString(), sym_ptr);
- registerSym("current_machine", sym_ptr);
- m_sym_vec.insertAtBottom(sym_ptr); // Holder for the allocated Sym objects.
-
- Map<string, Symbol*> m;
- m_machine_component_map_vec.add(sym_ptr->toString(),m);
-
-}
-
-Type* SymbolTable::getType(string ident) const
-{
- return dynamic_cast<Type*>(getSym(ident));
-}
-
-Var* SymbolTable::getVar(string ident) const
-{
- return dynamic_cast<Var*>(getSym(ident));
-}
-
-Func* SymbolTable::getFunc(string ident) const
-{
- return dynamic_cast<Func*>(getSym(ident));
-}
-
-StateMachine* SymbolTable::getStateMachine(string ident) const
-{
- return dynamic_cast<StateMachine*>(getSym(ident));
-}
-
-void SymbolTable::pushFrame()
-{
- m_depth++;
- m_sym_map_vec.expand(1);
- m_sym_map_vec[m_depth].clear();
-}
-
-void SymbolTable::popFrame()
-{
- m_depth--;
- assert(m_depth >= 0);
- m_sym_map_vec.expand(-1);
-}
-
-void SymbolTable::writeCFiles(string path) const
-{
- int size = m_sym_vec.size();
- {
- // Write the Types.hh include file for the types
- ostringstream sstr;
- sstr << "/** Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< " */" << endl;
- sstr << endl;
- sstr << "#include \"mem/ruby/slicc_interface/RubySlicc_includes.hh\"" << endl;
- for(int i=0; i<size; i++) {
- Type* type = dynamic_cast<Type*>(m_sym_vec[i]);
- if (type != NULL && !type->isPrimitive()) {
- sstr << "#include \"mem/protocol/" << type->cIdent() << ".hh" << "\"" << endl;
- }
- }
- conditionally_write_file(path + "/Types.hh", sstr);
- }
-
- // Write all the symbols
- for(int i=0; i<size; i++) {
- m_sym_vec[i]->writeCFiles(path + '/');
- }
-
- writeControllerFactory(path);
-}
-
-void SymbolTable::writeControllerFactory(string path) const
-{
- ostringstream sstr;
- int size = m_sym_vec.size();
-
- sstr << "/** \\file ControllerFactory.hh " << endl;
- sstr << " * Auto generatred C++ code started by " << __FILE__ << ":" << __LINE__ << endl;
- sstr << " */" << endl << endl;
-
- sstr << "#ifndef CONTROLLERFACTORY_H" << endl;
- sstr << "#define CONTROLLERFACTORY_H" << endl;
- sstr << endl;
-
- Vector< string > controller_types;
-
- // includes
- sstr << "#include <string>" << endl;
- sstr << "class Network;" << endl;
- sstr << "class AbstractController;" << endl;
- sstr << endl;
-
- sstr << "class ControllerFactory {" << endl;
- sstr << "public:" << endl;
- sstr << " static AbstractController* createController(const std::string & controller_type, const std::string & name);" << endl;
- sstr << "};" << endl;
- sstr << endl;
-
- sstr << "#endif // CONTROLLERFACTORY_H" << endl;
- conditionally_write_file(path + "/ControllerFactory.hh", sstr);
-
- // ControllerFactory.cc file
-
- sstr.str("");
-
- sstr << "/** \\file ControllerFactory.cc " << endl;
- sstr << " * Auto generatred C++ code started by " << __FILE__ << ":" << __LINE__ << endl;
- sstr << " */" << endl << endl;
-
- // includes
- sstr << "#include \"mem/protocol/ControllerFactory.hh\"" << endl;
- sstr << "#include \"mem/ruby/slicc_interface/AbstractController.hh\"" << endl;
- sstr << "#include \"mem/protocol/MachineType.hh\"" << endl;
- for(int i=0; i<size; i++) {
- StateMachine* machine = dynamic_cast<StateMachine*>(m_sym_vec[i]);
- if (machine != NULL) {
- sstr << "#include \"mem/protocol/" << machine->getIdent() << "_Controller.hh\"" << endl;
- controller_types.insertAtBottom(machine->getIdent());
- }
- }
- sstr << endl;
-
- sstr << "AbstractController* ControllerFactory::createController(const std::string & controller_type, const std::string & name) {" << endl;
- for (int i=0;i<controller_types.size();i++) {
- sstr << " if (controller_type == \"" << controller_types[i] << "\")" << endl;
- sstr << " return new " << controller_types[i] << "_Controller(name);" << endl;
- }
- sstr << " assert(0); // invalid controller type" << endl;
- sstr << " return NULL;" << endl;
- sstr << "}" << endl;
- conditionally_write_file(path + "/ControllerFactory.cc", sstr);
-}
-
-Vector<StateMachine*> SymbolTable::getStateMachines() const
-{
- Vector<StateMachine*> machine_vec;
- int size = m_sym_vec.size();
- for(int i=0; i<size; i++) {
- StateMachine* type = dynamic_cast<StateMachine*>(m_sym_vec[i]);
- if (type != NULL) {
- machine_vec.insertAtBottom(type);
- }
- }
- return machine_vec;
-}
-
-void SymbolTable::writeHTMLFiles(string path) const
-{
- // Create index.html
- {
- ostringstream out;
- createHTMLindex(path, out);
- conditionally_write_file(path + "index.html", out);
- }
-
- // Create empty.html
- {
- ostringstream out;
- out << "<HTML></HTML>";
- conditionally_write_file(path + "empty.html", out);
- }
-
- // Write all the symbols
- int size = m_sym_vec.size();
- for(int i=0; i<size; i++) {
- m_sym_vec[i]->writeHTMLFiles(path);
- }
-}
-
-void write_file(string filename, ostringstream& sstr)
-{
- ofstream out;
-
- out.open(filename.c_str());
- out << sstr.str();
- out.close();
-}
-
-void SymbolTable::writeMIFFiles(string path) const
-{
- int size = m_sym_vec.size();
- for(int i=0; i<size; i++) {
- ostringstream states, events, actions, transitions;
- StateMachine* machine = dynamic_cast<StateMachine*>(m_sym_vec[i]);
- if (machine != NULL) {
- printStateTableMIF(*machine, states);
- write_file(path + machine->getIdent() + "_states.mif", states);
- printEventTableMIF(*machine, events);
- write_file(path + machine->getIdent() + "_events.mif", events);
- printActionTableMIF(*machine, actions);
- write_file(path + machine->getIdent() + "_actions.mif", actions);
- printTransitionTableMIF(*machine, transitions);
- write_file(path + machine->getIdent() + "_transitions.mif", transitions);
- }
- }
-}
-
-
-void SymbolTable::print(ostream& out) const
-{
- out << "[SymbolTable]"; // FIXME
-}
diff --git a/src/mem/slicc/symbols/SymbolTable.hh b/src/mem/slicc/symbols/SymbolTable.hh
deleted file mode 100644
index 90d3f48c3..000000000
--- a/src/mem/slicc/symbols/SymbolTable.hh
+++ /dev/null
@@ -1,121 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * SymbolTable.hh
- *
- * Description:
- *
- * $Id$
- *
- * */
-
-#ifndef SYMBOLTABLE_H
-#define SYMBOLTABLE_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/gems_common/Map.hh"
-#include "mem/gems_common/Vector.hh"
-
-#include "mem/slicc/symbols/Symbol.hh"
-#include "mem/slicc/symbols/Type.hh"
-#include "mem/slicc/symbols/Var.hh"
-#include "mem/slicc/symbols/Func.hh"
-#include "mem/slicc/symbols/StateMachine.hh"
-
-class SymbolTable;
-
-extern SymbolTable g_sym_table;
-
-class SymbolTable {
-public:
- // Constructors
- SymbolTable();
-
- // Destructor
- ~SymbolTable();
-
- // Public Methods
- void newSym(Symbol* sym_ptr);
- void registerSym(string id, Symbol* sym_ptr);
- Symbol* getSym(string id) const;
-
- // used to cheat-- that is, access components in other machines
- void newMachComponentSym(Symbol* sym_ptr);
- Var* getMachComponentVar(string mach, string ident);
-
- void newCurrentMachine(StateMachine* machine_ptr);
- StateMachine* getStateMachine(string ident) const;
- StateMachine* getStateMachine() const { return getStateMachine("current_machine"); }
- Type* getType(string ident) const;
-
- Var* getVar(string ident) const;
- Func* getFunc(string ident) const;
-
- void pushFrame();
- void popFrame();
-
- Vector<StateMachine*> getStateMachines() const;
-
- void writeCFiles(string path) const;
- void writeHTMLFiles(string path) const;
- void writeMIFFiles(string path) const;
-
- void print(ostream& out) const;
-private:
- // Private Methods
- void registerGlobalSym(string id, Symbol* sym_ptr);
- void writeControllerFactory(string path) const;
-
- // Private copy constructor and assignment operator
- SymbolTable(const SymbolTable& obj);
- SymbolTable& operator=(const SymbolTable& obj);
-
- // Data Members (m_ prefix)
- Vector<Symbol*> m_sym_vec;
- Vector<Map<string, Symbol*> > m_sym_map_vec;
- Map<string, Map<string, Symbol*> > m_machine_component_map_vec;
- int m_depth;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const SymbolTable& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const SymbolTable& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //SYMBOLTABLE_H
diff --git a/src/mem/slicc/symbols/SymbolTable.py b/src/mem/slicc/symbols/SymbolTable.py
new file mode 100644
index 000000000..6b1bf13e6
--- /dev/null
+++ b/src/mem/slicc/symbols/SymbolTable.py
@@ -0,0 +1,221 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.util import code_formatter
+
+from slicc.generate import html
+from slicc.symbols.StateMachine import StateMachine
+from slicc.symbols.Type import Type
+from slicc.util import Location
+
+class SymbolTable(object):
+ def __init__(self):
+ self.sym_vec = []
+ self.sym_map_vec = [ {} ]
+ self.machine_components = {}
+
+ pairs = {}
+ pairs["enumeration"] = "yes"
+ MachineType = Type(self, "MachineType", Location("init", 0), pairs)
+ self.newSymbol(MachineType)
+
+ pairs = {}
+ pairs["primitive"] = "yes"
+ pairs["external"] = "yes"
+ void = Type(self, "void", Location("init", 0), pairs)
+ self.newSymbol(void)
+
+ def __repr__(self):
+ return "[SymbolTable]" # FIXME
+
+ def newSymbol(self, sym):
+ self.registerSym(str(sym), sym)
+ self.sym_vec.append(sym)
+
+ def registerSym(self, id, sym):
+ # Check for redeclaration (in the current frame only)
+ if id in self.sym_map_vec[-1]:
+ sym.error("Symbol '%s' redeclared in same scope.", id)
+
+ # FIXME - warn on masking of a declaration in a previous frame
+ self.sym_map_vec[-1][id] = sym
+
+ def find(self, ident, types=None):
+ for sym_map in reversed(self.sym_map_vec):
+ try:
+ symbol = sym_map[ident]
+ except KeyError:
+ continue
+
+ if types is not None:
+ if not isinstance(symbol, types):
+ symbol.error("Symbol '%s' is not of types '%s'.",
+ symbol,
+ types)
+
+ return symbol
+
+ return None
+
+ def newMachComponentSym(self, symbol):
+ # used to cheat-- that is, access components in other machines
+ machine = self.find("current_machine", StateMachine)
+ if machine:
+ self.machine_components[str(machine)][str(symbol)] = symbol
+
+ def newCurrentMachine(self, sym):
+ self.registerGlobalSym(str(sym), sym)
+ self.registerSym("current_machine", sym)
+ self.sym_vec.append(sym)
+
+ self.machine_components[str(sym)] = {}
+
+ @property
+ def state_machine(self):
+ return self.find("current_machine", StateMachine)
+
+ def pushFrame(self):
+ self.sym_map_vec.append({})
+
+ def popFrame(self):
+ assert len(self.sym_map_vec) > 0
+ self.sym_map_vec.pop()
+
+ def registerGlobalSym(self, ident, symbol):
+ # Check for redeclaration (global frame only)
+ if ident in self.sym_map_vec[0]:
+ symbol.error("Symbol '%s' redeclared in global scope." % ident)
+
+ self.sym_map_vec[0][ident] = symbol
+
+ def getAllType(self, type):
+ for symbol in self.sym_vec:
+ if isinstance(symbol, type):
+ yield symbol
+
+ def writeCodeFiles(self, path):
+ code = code_formatter()
+ code('''
+/** Auto generated C++ code started by $__file__:$__line__ */
+
+#include "mem/ruby/slicc_interface/RubySlicc_includes.hh"
+''')
+ for symbol in self.sym_vec:
+ if isinstance(symbol, Type) and not symbol.isPrimitive:
+ code('#include "mem/protocol/${{symbol.c_ident}}.hh"')
+
+ code.write(path, "Types.hh")
+
+ for symbol in self.sym_vec:
+ symbol.writeCodeFiles(path)
+
+ self.writeControllerFactory(path)
+
+ def writeControllerFactory(self, path):
+ code = code_formatter()
+
+ code('''
+/** \\file ControllerFactory.hh
+ * Auto generatred C++ code started by $__file__:$__line__
+ */
+
+#ifndef CONTROLLERFACTORY_H
+#define CONTROLLERFACTORY_H
+
+#include <string>
+class Network;
+class AbstractController;
+
+class ControllerFactory {
+ public:
+ static AbstractController *createController(const std::string &controller_type, const std::string &name);
+};
+#endif // CONTROLLERFACTORY_H''')
+ code.write(path, "ControllerFactory.hh")
+
+ code = code_formatter()
+ code('''
+/** \\file ControllerFactory.cc
+ * Auto generatred C++ code started by $__file__:$__line__
+ */
+
+#include "mem/protocol/ControllerFactory.hh"
+#include "mem/ruby/slicc_interface/AbstractController.hh"
+#include "mem/protocol/MachineType.hh"
+''')
+
+ controller_types = []
+ for symbol in self.getAllType(StateMachine):
+ code('#include "mem/protocol/${{symbol.ident}}_Controller.hh"')
+ controller_types.append(symbol.ident)
+
+ code('''
+AbstractController *ControllerFactory::createController(const std::string &controller_type, const std::string &name) {
+''')
+
+ for ct in controller_types:
+ code('''
+ if (controller_type == "$ct")
+ return new ${ct}_Controller(name);
+''')
+
+ code('''
+ assert(0); // invalid controller type
+ return NULL;
+}
+''')
+ code.write(path, "ControllerFactory.cc")
+
+ def writeHTMLFiles(self, path):
+ machines = list(self.getAllType(StateMachine))
+ if len(machines) > 1:
+ name = "%s_table.html" % machines[0].ident
+ else:
+ name = "empty.html"
+
+ code = code_formatter()
+ code('''
+<html>
+<head>
+<title>$path</title>
+</head>
+<frameset rows="*,30">
+ <frame name="Table" src="$name">
+ <frame name="Status" src="empty.html">
+</frameset>
+</html>
+''')
+ code.write(path, "index.html")
+
+ code = code_formatter()
+ code("<HTML></HTML>")
+ code.write(path, "empty.html")
+
+ for symbol in self.sym_vec:
+ symbol.writeHTMLFiles(path)
+
+__all__ = [ "SymbolTable" ]
diff --git a/src/mem/slicc/symbols/Transition.cc b/src/mem/slicc/symbols/Transition.cc
deleted file mode 100644
index d6d348166..000000000
--- a/src/mem/slicc/symbols/Transition.cc
+++ /dev/null
@@ -1,173 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * $Id$
- *
- * */
-
-#include "mem/slicc/symbols/Transition.hh"
-#include "mem/slicc/symbols/State.hh"
-#include "mem/slicc/symbols/Event.hh"
-#include "mem/slicc/symbols/Action.hh"
-#include "mem/gems_common/util.hh"
-#include "mem/slicc/symbols/Var.hh"
-
-Transition::Transition(string state, string event, string nextState,
- const Vector<string>& actionList,
- const Location& location,
- const Map<string, string>& pairMap)
- : Symbol(state + "|" + event, location, pairMap)
-{
- m_state = state;
- m_event = event;
- m_nextState = nextState;
- m_actionList = actionList;
-
- // Ptrs are undefined at this point
- m_statePtr = NULL;
- m_eventPtr = NULL;
- m_nextStatePtr = NULL;
- m_actionPtrsValid = false;
-}
-
-void Transition::checkIdents(const Vector<State*>& states,
- const Vector<Event*>& events,
- const Vector<Action*>& actions)
-{
- m_statePtr = findIndex(states, m_state);
- m_eventPtr = findIndex(events, m_event);
- m_nextStatePtr = findIndex(states, m_nextState);
-
- for(int i=0; i < m_actionList.size(); i++) {
- Action* action_ptr = findIndex(actions, m_actionList[i]);
- int size = action_ptr->getResources().keys().size();
- for (int j=0; j < size; j++) {
- Var* var_ptr = action_ptr->getResources().keys()[j];
- if (var_ptr->getType()->cIdent() != "DNUCAStopTable") {
- int num = atoi((action_ptr->getResources().lookup(var_ptr)).c_str());
- if (m_resources.exist(var_ptr)) {
- num += atoi((m_resources.lookup(var_ptr)).c_str());
- }
- m_resources.add(var_ptr, int_to_string(num));
- } else {
- m_resources.add(var_ptr, action_ptr->getResources().lookup(var_ptr));
- }
- }
- m_actionPtrs.insertAtBottom(action_ptr);
- }
- m_actionPtrsValid = true;
-}
-
-const string& Transition::getStateShorthand() const
-{
- assert(m_statePtr != NULL);
- return m_statePtr->getShorthand();
-}
-
-const string& Transition::getEventShorthand() const
-{
- assert(m_eventPtr != NULL);
- return m_eventPtr->getShorthand();
-}
-
-const string& Transition::getNextStateShorthand() const
-{
- assert(m_nextStatePtr != NULL);
- return m_nextStatePtr->getShorthand();
-}
-
-string Transition::getActionShorthands() const
-{
- assert(m_actionPtrsValid);
- string str;
- int numActions = m_actionPtrs.size();
- for (int i=0; i<numActions; i++) {
- str += m_actionPtrs[i]->getShorthand();
- }
- return str;
-}
-
-void Transition::print(ostream& out) const
-{
- out << "[Transition: ";
- out << "(" << m_state;
- if (m_statePtr != NULL) {
- out << ":" << *m_statePtr;
- }
- out << ", " << m_event;
- if (m_eventPtr != NULL) {
- out << ":" << *m_eventPtr;
- }
- out << ") -> ";
- out << m_nextState;
- if (m_nextStatePtr != NULL) {
- out << ":" << *m_nextStatePtr;
- }
- out << ", ";
- out << m_actionList;
- out << "]";
-}
-
-Event* Transition::findIndex(const Vector<Event*>& vec, string ident)
-{
- int size = vec.size();
- for(int i=0; i<size; i++) {
- if (ident == vec[i]->getIdent()) {
- return vec[i];
- }
- }
- error("Event not found: " + ident);
- return NULL;
-}
-
-State* Transition::findIndex(const Vector<State*>& vec, string ident)
-{
- int size = vec.size();
- for(int i=0; i<size; i++) {
- if (ident == vec[i]->getIdent()) {
- return vec[i];
- }
- }
- error("State not found: " + ident);
- return NULL;
-}
-
-Action* Transition::findIndex(const Vector<Action*>& vec, string ident)
-{
- int size = vec.size();
- for(int i=0; i<size; i++) {
- if (ident == vec[i]->getIdent()) {
- return vec[i];
- }
- }
- error("Action not found: " + ident);
- return NULL;
-}
-
diff --git a/src/mem/slicc/symbols/Transition.hh b/src/mem/slicc/symbols/Transition.hh
deleted file mode 100644
index 75d6da4e9..000000000
--- a/src/mem/slicc/symbols/Transition.hh
+++ /dev/null
@@ -1,120 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Transition.hh
- *
- * Description:
- *
- * $Id$
- *
- * */
-
-#ifndef TRANSITION_H
-#define TRANSITION_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/gems_common/Vector.hh"
-#include "mem/slicc/symbols/Symbol.hh"
-
-class State;
-class Event;
-class Action;
-class Var;
-
-class Transition : public Symbol {
-public:
- // Constructors
- Transition(string state, string event, string nextState,
- const Vector<string>& actionList,
- const Location& location,
- const Map<string, string>& pairMap);
- // Destructor
- ~Transition() { }
-
- // Public Methods
- State* getStatePtr() const { assert(m_statePtr != NULL); return m_statePtr; }
- Event* getEventPtr() const { assert(m_eventPtr != NULL); return m_eventPtr; }
- State* getNextStatePtr() const { assert(m_nextStatePtr != NULL); return m_nextStatePtr; }
-
- // int getStateIndex() const { assert(m_statePtr != NULL); return m_statePtr->getIndex(); }
- // int getEventIndex() const { assert(m_eventPtr != NULL); return m_eventPtr->getIndex(); }
- // int getNextStateIndex() const { assert(m_nextStatePtr != NULL); return m_nextStatePtr->getIndex(); }
- void checkIdents(const Vector<State*>& states,
- const Vector<Event*>& events,
- const Vector<Action*>& actions);
-
- const string& getStateShorthand() const;
- const string& getEventShorthand() const;
- const string& getNextStateShorthand() const;
- string getActionShorthands() const;
- const Vector<Action*>& getActions() const { assert(m_actionPtrsValid); return m_actionPtrs; }
- const Map<Var*, string>& getResources() const { assert(m_actionPtrsValid); return m_resources; }
-
- void print(ostream& out) const;
-
- // Default copy constructor and assignment operator
- // Transition(const Transition& obj);
- // Transition& operator=(const Transition& obj);
-private:
- // Private Methods
- Event* findIndex(const Vector<Event*>& vec, string ident);
- State* findIndex(const Vector<State*>& vec, string ident);
- Action* findIndex(const Vector<Action*>& vec, string ident);
-
- // Data Members (m_ prefix)
- string m_state;
- string m_event;
- string m_nextState;
-
- State* m_statePtr;
- Event* m_eventPtr;
- State* m_nextStatePtr;
-
- Vector<string> m_actionList;
- Vector<Action*> m_actionPtrs;
- Map<Var*, string> m_resources;
- bool m_actionPtrsValid;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const Transition& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const Transition& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //TRANSITION_H
diff --git a/src/mem/slicc/symbols/Transition.py b/src/mem/slicc/symbols/Transition.py
new file mode 100644
index 000000000..1bf09048a
--- /dev/null
+++ b/src/mem/slicc/symbols/Transition.py
@@ -0,0 +1,61 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.symbols.Symbol import Symbol
+
+class Transition(Symbol):
+ def __init__(self, table, machine, state, event, nextState, actions,
+ location, pairs):
+ ident = "%s|%s" % (state, event)
+ super(Transition, self).__init__(table, ident, location, pairs)
+
+ self.state = machine.states[state]
+ self.event = machine.events[event]
+ self.nextState = machine.states[nextState]
+ self.actions = [ machine.actions[a] for a in actions ]
+ self.resources = {}
+
+ for action in self.actions:
+ for var,value in action.resources.iteritems():
+ if var.type.ident != "DNUCAStopTable":
+ num = int(value)
+ if var in self.resources:
+ num += int(value)
+ self.resources[var] = str(num)
+ else:
+ self.resources[var] = value
+
+ def __repr__(self):
+ return "[Transition: (%r, %r) -> %r, %r]" % \
+ (self.state, self.event, self.nextState, self.actions)
+
+ def getActionShorthands(self):
+ assert self.actions
+
+ return ''.join(a.short for a in self.actions)
+
+__all__ = [ "Transition" ]
diff --git a/src/mem/slicc/symbols/Type.cc b/src/mem/slicc/symbols/Type.cc
deleted file mode 100644
index 5afe53423..000000000
--- a/src/mem/slicc/symbols/Type.cc
+++ /dev/null
@@ -1,779 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Type.cc
- *
- * Description: See Type.hh
- *
- * $Id$
- * */
-
-#include "mem/slicc/symbols/Type.hh"
-#include "mem/slicc/generator/fileio.hh"
-#include "mem/gems_common/Map.hh"
-#include "mem/slicc/symbols/StateMachine.hh"
-
-Type::Type(string id, const Location& location,
- const Map<string, string>& pairs,
- StateMachine* machine_ptr)
- : Symbol(id, location, pairs)
-{
- if (machine_ptr == NULL) {
- m_c_id = id;
- } else if (isExternal() || isPrimitive()) {
- if (existPair("external_name")) {
- m_c_id = lookupPair("external_name");
- } else {
- m_c_id = id;
- }
- } else {
- m_c_id = machine_ptr->toString() + "_" + id; // Append with machine name
- }
-
- if(existPair("desc")){
- m_desc = lookupPair("desc");
- } else {
- m_desc = "No description avaliable";
- }
-
- // check for interface that this Type implements
- if(existPair("interface")) {
- string interface = lookupPair("interface");
- if(interface == "Message" || interface == "NetworkMessage") {
- addPair("message", "yes");
- }
- if(interface == "NetworkMessage") {
- addPair("networkmessage", "yes");
- }
- }
-
- // FIXME - all of the following id comparisons are fragile hacks
- if ((getIdent() == "CacheMemory") || (getIdent() == "NewCacheMemory") ||
- (getIdent() == "TLCCacheMemory") || (getIdent() == "DNUCACacheMemory") ||
- (getIdent() == "DNUCABankCacheMemory") || (getIdent() == "L2BankCacheMemory") ||
- (getIdent() == "CompressedCacheMemory") || (getIdent() == "PrefetchCacheMemory")) {
- addPair("cache", "yes");
- }
-
- if ((getIdent() == "TBETable") || (getIdent() == "DNUCATBETable") || (getIdent() == "DNUCAStopTable")) {
- addPair("tbe", "yes");
- }
-
- if ((getIdent() == "NewTBETable")) {
- addPair("newtbe", "yes");
- }
-
- if ((getIdent() == "TimerTable")) {
- addPair("timer", "yes");
- }
-
- if ((getIdent() == "DirectoryMemory")) {
- addPair("dir", "yes");
- }
-
- if ((getIdent() == "PersistentTable")) {
- addPair("persistent", "yes");
- }
-
- if ((getIdent() == "Prefetcher")) {
- addPair("prefetcher", "yes");
- }
-
- if ((getIdent() == "DNUCA_Movement")) {
- addPair("mover", "yes");
- }
-
- if (id == "MachineType") {
- m_isMachineType = true;
- } else {
- m_isMachineType = false;
- }
-}
-
-// Return false on error
-bool Type::dataMemberAdd(string id, Type* type_ptr, Map<string, string>& pairs,
- string* init_code)
-{
- if (dataMemberExist(id)) {
- return false; // Error
- } else {
- m_data_member_map.add(id, type_ptr);
- m_data_member_ident_vec.insertAtBottom(id);
- m_data_member_type_vec.insertAtBottom(type_ptr);
- m_data_member_pairs_vec.insertAtBottom(pairs);
- m_data_member_init_code_vec.insertAtBottom(init_code);
- }
-
- return true;
-}
-
-string Type::methodId(string name,
- const Vector<Type*>& param_type_vec)
-{
- string paramStr = "";
- for (int i = 0; i < param_type_vec.size(); i++) {
- paramStr += "_"+param_type_vec[i]->cIdent();
- }
- return name+paramStr;
-}
-
-bool Type::methodAdd(string name,
- Type* return_type_ptr,
- const Vector<Type*>& param_type_vec)
-{
- string id = methodId(name, param_type_vec);
- if (methodExist(id)) {
- return false; // Error
- } else {
- m_method_return_type_map.add(id, return_type_ptr);
- m_method_param_type_map.add(id, param_type_vec);
- return true;
- }
-}
-
-bool Type::enumAdd(string id, Map<string, string> pairs_map)
-{
- if (enumExist(id)) {
- return false;
- } else {
- m_enum_map.add(id, true);
- m_enum_vec.insertAtBottom(id);
- m_enum_pairs.insertAtBottom(pairs_map);
-
- // Add default
- if (!existPair("default")) {
- addPair("default", cIdent()+"_NUM");
- }
-
- return true;
- }
-}
-
-void Type::writeCFiles(string path)
-{
- if (isExternal()) {
- // Do nothing
- } else if (isEnumeration()) {
- printEnumH(path);
- printEnumC(path);
- } else { // User defined structs and messages
- printTypeH(path);
- printTypeC(path);
- }
-}
-
-void Type::printTypeH(string path) const
-{
- ostringstream out;
- int size = m_data_member_type_vec.size();
- string type_name = cIdent(); // Identifier for the type in C
-
- // Header
- out << "/** \\file " << type_name << ".hh" << endl;
- out << " * " << endl;
- out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
- out << " */" << endl;
- out << endl;
- out << "#ifndef " << type_name << "_H" << endl;
- out << "#define " << type_name << "_H" << endl;
- out << endl;
-
- // Include all of the #includes needed
- out << "#include \"mem/ruby/common/Global.hh\"" << endl;
- out << "#include \"mem/gems_common/Allocator.hh\"" << endl;
- for (int i=0; i < size; i++) {
- Type* type = m_data_member_type_vec[i];
- if (!type->isPrimitive()) {
- out << "#include \"mem/protocol/" << type->cIdent() << ".hh" << "\"" << endl;
- }
- }
- string interface = "";
- if(existPair("interface")) {
- interface = lookupPair("interface");
- out << "#include \"mem/protocol/" << interface << ".hh\"" << endl;
- }
-
- // Class definition
- out << "class " << type_name;
-
- if(interface != "") {
- out << " : public " << interface ;
- }
-
- out << " {" << endl;
- out << "public:" << endl;
-
- // ******** Default constructor ********
-
- out << " " << type_name << "() " << endl;
-
- // Call superclass constructor
- if (interface != "") {
- out << " : " << interface << "()" << endl;
- }
-
- out << " {" << endl;
-
- if(!isGlobal()) {
- for (int i=0; i < size; i++) {
-
- Type* type_ptr = m_data_member_type_vec[i];
- string id = m_data_member_ident_vec[i];
- if (m_data_member_pairs_vec[i].exist("default")) {
- // look for default value
- string default_value = m_data_member_pairs_vec[i].lookup("default");
- out << " m_" << id << " = " << default_value << "; // default for this field " << endl;
- } else if (type_ptr->hasDefault()) {
- // Look for the type default
- string default_value = type_ptr->getDefault();
- out << " m_" << id << " = " << default_value << "; // default value of " << type_ptr->cIdent() << endl;
- } else {
- out << " // m_" << id << " has no default" << endl;
- }
- }
- } // end of if(!isGlobal())
- out << " }" << endl;
-
- // ******** Default destructor ********
- out << " ";
- out << "~" << type_name << "() { };" << endl;
-
- // ******** Full init constructor ********
- if(! isGlobal()) {
- out << " " << type_name << "(";
-
- for (int i=0; i < size; i++) {
- if (i != 0) {
- out << ", ";
- }
- Type* type = m_data_member_type_vec[i];
- string id = m_data_member_ident_vec[i];
- out << "const " << type->cIdent() << "& local_" << id;
- }
-
- if (isMessage()) {
- out << ", const unsigned local_proc_id" << flush;
- }
-
- out << ")" << endl;
-
- // Call superclass constructor
- if (interface != "") {
- out << " : " << interface << "()" << endl;
- }
-
- out << " {" << endl;
- for (int i=0; i < size; i++) {
- Type* type_ptr = m_data_member_type_vec[i];
- string id = m_data_member_ident_vec[i];
- out << " m_" << id << " = local_" << id << ";" << endl;
- if (m_data_member_pairs_vec[i].exist("nextLineCallHack")) {
- string next_line_value = m_data_member_pairs_vec[i].lookup("nextLineCallHack");
- out << " m_" << id << next_line_value << ";" << endl;
- }
- }
- if (isMessage()) {
- out << " proc_id = local_proc_id;" << endl << flush;
- }
- out << " }" << endl;
- } // end of if(!isGlobal())
-
- // create a static factory method
- if (interface != "") {
- out << " static " << interface << "* create() {" << endl;
- out << " return new " << type_name << "(); " << endl;
- out << " }" << endl;
- }
-
- // bobba -
- //******** Partial init constructor ********
- //** Constructor needs only the first n-1 data members for init
- //** HACK to create objects with partially specified data members
- //** Need to get rid of this and use hierarchy instead
-// if(! isGlobal()) {
-// out << " " << type_name << "(";
-
-// for (int i=0; i < size-1; i++) {
-// if (i != 0) {
-// out << ", ";
-// }
-// Type* type = m_data_member_type_vec[i];
-// string id = m_data_member_ident_vec[i];
-// out << "const " << type->cIdent() << "& local_" << id;
-// }
-// out << ")" << endl;
-
-// // Call superclass constructor
-// if (interface != "") {
-// out << " : " << interface << "()" << endl;
-// }
-
-// out << " {" << endl;
-// for (int i=0; i < size-1; i++) {
-// Type* type_ptr = m_data_member_type_vec[i];
-// string id = m_data_member_ident_vec[i];
-// out << " m_" << id << " = local_" << id << ";" << endl;
-// if (m_data_member_pairs_vec[i].exist("nextLineCallHack")) {
-// string next_line_value = m_data_member_pairs_vec[i].lookup("nextLineCallHack");
-// out << " m_" << id << next_line_value << ";" << endl;
-// }
-
-// }
-// out << " }" << endl;
-// } // end of if(!isGlobal())
-
- // ******** Message member functions ********
- // FIXME: those should be moved into slicc file, slicc should support more of
- // the c++ class inheritance
-
- if (isMessage()) {
- out << " Message* clone() const { checkAllocator(); return s_allocator_ptr->allocate(*this); }" << endl;
- out << " void destroy() { checkAllocator(); s_allocator_ptr->deallocate(this); }" << endl;
- out << " static Allocator<" << type_name << ">* s_allocator_ptr;" << endl;
- out << " static void checkAllocator() { if (s_allocator_ptr == NULL) { s_allocator_ptr = new Allocator<" << type_name << ">; }}" << endl;
- }
-
- if(!isGlobal()) {
- // const Get methods for each field
- out << " // Const accessors methods for each field" << endl;
- for (int i=0; i < size; i++) {
- Type* type_ptr = m_data_member_type_vec[i];
- string type = type_ptr->cIdent();
- string id = m_data_member_ident_vec[i];
- out << "/** \\brief Const accessor method for " << id << " field." << endl;
- out << " * \\return " << id << " field" << endl;
- out << " */" << endl;
- out << " const " << type << "& get" << id
- << "() const { return m_" << id << "; }" << endl;
- }
-
- out << endl;
-
- // Non-const Get methods for each field
- out << " // Non const Accessors methods for each field" << endl;
- for (int i=0; i < size; i++) {
- Type* type_ptr = m_data_member_type_vec[i];
- string type = type_ptr->cIdent();
- string id = m_data_member_ident_vec[i];
- out << "/** \\brief Non-const accessor method for " << id << " field." << endl;
- out << " * \\return " << id << " field" << endl;
- out << " */" << endl;
- out << " " << type << "& get" << id
- << "() { return m_" << id << "; }" << endl;
- }
-
- out << endl;
-
- // Set methods for each field
- out << " // Mutator methods for each field" << endl;
- for (int i=0; i < size; i++) {
- Type* type_ptr = m_data_member_type_vec[i];
- string type = type_ptr->cIdent();
- string id = m_data_member_ident_vec[i];
- out << "/** \\brief Mutator method for " << id << " field */" << endl;
- out << " void set" << id << "(const " << type << "& local_"
- << id << ") { m_" << id << " = local_" << id << "; }" << endl;
- }
-
- out << endl;
- } // end of if(!isGlobal())
-
- out << " void print(ostream& out) const;" << endl;
- out << "//private:" << endl;
-
- // Data members for each field
- for (int i=0; i < size; i++) {
- if (!m_data_member_pairs_vec[i].exist("abstract")) {
- out << " ";
- // global structure
- if(isGlobal()) out << "static const ";
-
- Type* type = m_data_member_type_vec[i];
- string id = m_data_member_ident_vec[i];
- out << type->cIdent() << " m_" << id;
-
- // init value
- string* init_code = m_data_member_init_code_vec[i];
- if(init_code) {
- // only global structure can have init value here
- assert(isGlobal());
- out << " = " << *init_code << " ";
- }
- out << ";";
- if (m_data_member_pairs_vec[i].exist("desc")) {
- string desc = m_data_member_pairs_vec[i].lookup("desc");
- out << " /**< " << desc << "*/";
- }
- out << endl;
- }
- }
-
- if (isMessage()) {
- out << " unsigned proc_id;" << endl << flush;
- }
-
- out << "};" << endl; // End class
-
- out << "// Output operator declaration" << endl;
- out << "ostream& operator<<(ostream& out, const " << type_name << "& obj);" << endl;
- out << endl;
- out << "// Output operator definition" << endl;
- out << "extern inline" << endl;
- out << "ostream& operator<<(ostream& out, const " << type_name << "& obj)" << endl;
- out << "{" << endl;
- out << " obj.print(out);" << endl;
- out << " out << flush;" << endl;
- out << " return out;" << endl;
- out << "}" << endl;
- out << endl;
- out << "#endif // " << type_name << "_H" << endl;
-
- // Write it out
- conditionally_write_file(path + type_name + ".hh", out);
-}
-
-void Type::printTypeC(string path) const
-{
- ostringstream out;
- int size = m_data_member_type_vec.size();
- string type_name = cIdent(); // Identifier for the type in C
-
- // Header
- out << "/** \\file " << type_name << ".cc" << endl;
- out << " * " << endl;
- out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
- out << " */" << endl;
- out << endl;
- out << "#include \"mem/protocol/" << type_name << ".hh\"" << endl;
- out << endl;
- if (isMessage()) {
- out << "Allocator<" << type_name << ">* " << type_name << "::s_allocator_ptr = NULL;" << endl;
- }
- out << "/** \\brief Print the state of this object */" << endl;
- out << "void " << type_name << "::print(ostream& out) const" << endl;
- out << "{" << endl;
- out << " out << \"[" << type_name << ": \";" << endl;
-
- // For each field
- for (int i=0; i < size; i++) {
- string id = m_data_member_ident_vec[i];
- out << " out << \"" << id << "=\" << m_" << id << " << \" \";" << endl;
- }
-
- if (isMessage()) {
- out << " out << \"" << "Time" << "=\" << getTime()" << " << \" \";" << endl;
- }
-
- // Trailer
- out << " out << \"]\";" << endl;
- out << "}" << endl;
-
- // Write it out
- conditionally_write_file(path + type_name + ".cc", out);
-}
-
-void Type::printEnumH(string path) const
-{
- ostringstream out;
- int size = m_enum_vec.size();
- string type_name = cIdent(); // Identifier for the type in C
- string type_desc = desc();
-
- // Header
- out << "/** \\file " << type_name << ".hh" << endl;
- out << " * " << endl;
- out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
- out << " */" << endl;
-
- out << "#ifndef " << type_name << "_H" << endl;
- out << "#define " << type_name << "_H" << endl;
- out << endl;
- // Include all of the #includes needed
- out << "#include \"mem/ruby/common/Global.hh\"" << endl;
- out << endl;
-
- // Class definition
- out << "/** \\enum " << type_name << endl;
- out << " * \\brief " << type_desc << endl;
- out << " */" << endl;
- out << "enum " << type_name << " {" << endl;
-
- out << " " << type_name << "_FIRST," << endl;
-
- // For each field
- for(int i = 0; i < size; i++ ) {
- string id = m_enum_vec[i];
- string description;
- if(m_enum_pairs[i].exist("desc")){
- description = m_enum_pairs[i].lookup("desc");
- } else {
- description = "No description avaliable";
- }
- if (i == 0) {
- out << " " << type_name << "_" << id << " = " << type_name << "_FIRST, /**< " << description << " */" << endl;
- }
- else {
- out << " " << type_name << "_" << id << ", /**< " << description << " */" << endl;
- }
- }
- out << " " << type_name << "_NUM" << endl;
- out << "};" << endl;
-
- // Code to convert from a string to the enumeration
- out << type_name << " string_to_" << type_name << "(const string& str);" << endl;
-
- // Code to convert state to a string
- out << "string " << type_name << "_to_string(const " << type_name << "& obj);" << endl;
-
- // Code to increment an enumeration type
- out << type_name << " &operator++( " << type_name << " &e);" << endl;
-
- // MachineType hack used to set the base component id for each Machine
- if (m_isMachineType) {
- out << "int " << type_name << "_base_level(const " << type_name << "& obj);" << endl;
- out << "MachineType " << type_name << "_from_base_level(int);" << endl;
- out << "int " << type_name << "_base_number(const " << type_name << "& obj);" << endl;
- out << "int " << type_name << "_base_count(const " << type_name << "& obj);" << endl;
- // out << "int " << type_name << "_chip_count(const " << type_name << "& obj, int chipID);" << endl;
-
- for(int i = 0; i < size; i++ ) {
- string id = m_enum_vec[i];
- out << "#define MACHINETYPE_" << id << " 1" << endl;
- }
- cout << endl;
- }
-
- // Trailer
- out << "ostream& operator<<(ostream& out, const " << type_name << "& obj);" << endl;
- out << endl;
- out << "#endif // " << type_name << "_H" << endl;
-
- // Write the file
- conditionally_write_file(path + type_name + ".hh", out);
-}
-
-void Type::printEnumC(string path) const
-{
- ostringstream out;
- int size = m_enum_vec.size();
- string type_name = cIdent(); // Identifier for the type in C
-
- // Header
- out << "/** \\file " << type_name << ".hh" << endl;
- out << " * " << endl;
- out << " * Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<< endl;
- out << " */" << endl;
-
- out << endl;
- out << "#include \"mem/protocol/" << type_name << ".hh\"" << endl;
- if (m_isMachineType) {
- out << "#include \"mem/protocol/ControllerFactory.hh\"" << endl;
- for( int i = 0; i<size; i++ ) {
- out << "#include \"mem/protocol/" << m_enum_vec[i] << "_Controller.hh\"" << endl;
- }
- out << endl;
- }
- out << endl;
-
- // Code for output operator
- out << "ostream& operator<<(ostream& out, const " << type_name << "& obj)" << endl;
- out << "{" << endl;
- out << " out << " << type_name << "_to_string(obj);" << endl;
- out << " out << flush;" << endl;
- out << " return out;" << endl;
- out << "}" << endl;
-
- // Code to convert state to a string
- out << endl;
- out << "string " << type_name << "_to_string(const " << type_name << "& obj)" << endl;
- out << "{" << endl;
- out << " switch(obj) {" << endl;
-
- // For each field
- for( int i = 0; i<size; i++ ) {
- out << " case " << type_name << "_" << m_enum_vec[i] << ":" << endl;
- out << " return \"" << m_enum_vec[i] << "\";" << endl;
- }
-
- // Trailer
- out << " default:" << endl;
- out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl;
- out << " return \"\";" << endl;
- out << " }" << endl;
- out << "}" << endl;
-
- // Code to convert from a string to the enumeration
- out << endl;
- out << type_name << " string_to_" << type_name << "(const string& str)" << endl;
- out << "{" << endl;
- out << " if (false) {" << endl;
-
- // For each field
- for( int i = 0; i<size; i++ ) {
- out << " } else if (str == \"" << m_enum_vec[i] << "\") {" << endl;
- out << " return " << type_name << "_" << m_enum_vec[i] << ";" << endl;
- }
-
- out << " } else {" << endl;
- out << " WARN_EXPR(str);" << endl;
- out << " ERROR_MSG(\"Invalid string conversion for type " << type_name << "\");" << endl;
- out << " }" << endl;
- out << "}" << endl;
-
- // Code to increment an enumeration type
- out << endl;
- out << type_name << "& operator++( " << type_name << "& e) {" << endl;
- out << " assert(e < " << type_name << "_NUM);" << endl;
- out << " return e = " << type_name << "(e+1);" << endl;
- out << "}" << endl;
-
- // MachineType hack used to set the base level and number of components for each Machine
- if (m_isMachineType) {
- out << endl;
- out << "/** \\brief returns the base vector index for each machine type to be used by NetDest " << endl;
- out << " * " << endl;
- out << " * \\return the base vector index for each machine type to be used by NetDest" << endl;
- out << " * \\see NetDest.hh" << endl;
- out << " */" << endl;
- out << "int " << type_name << "_base_level(const " << type_name << "& obj)" << endl;
- out << "{" << endl;
- out << " switch(obj) {" << endl;
-
- // For each field
- Vector < string > MachineNames;
- for( int i = 0; i<size; i++ ) {
- out << " case " << type_name << "_" << m_enum_vec[i] << ":" << endl;
- out << " return " << MachineNames.size() << ";" << endl;
- MachineNames.insertAtBottom(m_enum_vec[i]);
- }
-
- // total num
- out << " case " << type_name << "_NUM:" << endl;
- out << " return " << MachineNames.size() << ";" << endl;
-
- // Trailer
- out << " default:" << endl;
- out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl;
- out << " return -1;" << endl;
- out << " }" << endl;
- out << "}" << endl;
-
- out << "/** \\brief returns the machine type for each base vector index used by NetDest" << endl;
- out << " * " << endl;
- out << " * \\return the MachineTYpe" << endl;
- out << " */" << endl;
- out << "MachineType " << type_name << "_from_base_level(int type)" << endl;
- out << "{" << endl;
- out << " switch(type) {" << endl;
-
- // For each field
- MachineNames.clear();
- for( int i = 0; i<size; i++ ) {
- out << " case " << MachineNames.size() << ":" << endl;
- out << " return " << type_name << "_" << m_enum_vec[i] << ";" << endl;
- MachineNames.insertAtBottom(m_enum_vec[i]);
- }
-
- // Trailer
- out << " default:" << endl;
- out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl;
- out << " return MachineType_NUM;" << endl;
- out << " }" << endl;
- out << "}" << endl;
-
-
- out << endl;
- out << "/** \\brief The return value indicates the number of components created" << endl;
- out << " * before a particular machine's components" << endl;
- out << " * " << endl;
- out << " * \\return the base number of components for each machine" << endl;
- out << " */" << endl;
- out << "int " << type_name << "_base_number(const " << type_name << "& obj)" << endl;
- out << "{" << endl;
- out << " switch(obj) {" << endl;
-
- // For each field
- MachineNames.clear();
- for( int i = 0; i<size; i++ ) {
- out << " case " << type_name << "_" << m_enum_vec[i] << ":" << endl;
- out << " return 0";
- for ( int m = 0; m<MachineNames.size(); m++) {
- out << "+ " << MachineNames[m] << "_Controller::getNumControllers()";
- }
- out << ";" << endl;
- MachineNames.insertAtBottom(m_enum_vec[i]);
- }
-
- // total num
- out << " case " << type_name << "_NUM:" << endl;
- out << " return 0";
- for ( int m = 0; m<MachineNames.size(); m++) {
- out << "+ " << MachineNames[m] << "_Controller::getNumControllers()";
- }
- out << ";" << endl;
-
- // Trailer
- out << " default:" << endl;
- out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl;
- out << " return -1;" << endl;
- out << " }" << endl;
- out << "}" << endl;
-
-
- out << endl;
- out << "/** \\brief returns the total number of components for each machine" << endl;
- out << " * \\return the total number of components for each machine" << endl;
- out << " */" << endl;
- out << "int " << type_name << "_base_count(const " << type_name << "& obj)" << endl;
- out << "{" << endl;
- out << " switch(obj) {" << endl;
-
- // For each field
- for( int i = 0; i<size; i++ ) {
- out << " case " << type_name << "_" << m_enum_vec[i] << ":" << endl;
- out << " return " << m_enum_vec[i] << "_Controller::getNumControllers();" << endl;
- }
-
- // total num
- out << " case " << type_name << "_NUM:" << endl;
- // Trailer
- out << " default:" << endl;
- out << " ERROR_MSG(\"Invalid range for type " << type_name << "\");" << endl;
- out << " return -1;" << endl;
- out << " }" << endl;
- out << "}" << endl;
-
- out << endl;
-
- }
-
- // Write the file
- conditionally_write_file(path + type_name + ".cc", out);
-}
diff --git a/src/mem/slicc/symbols/Type.hh b/src/mem/slicc/symbols/Type.hh
deleted file mode 100644
index 07d661d3c..000000000
--- a/src/mem/slicc/symbols/Type.hh
+++ /dev/null
@@ -1,155 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Type.hh
- *
- * Description:
- *
- * $Id$
- *
- * */
-
-#ifndef TYPE_H
-#define TYPE_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/gems_common/Map.hh"
-#include "mem/slicc/symbols/Symbol.hh"
-
-class StateMachine;
-
-class Type : public Symbol {
-public:
- // Constructors
- Type(string id, const Location& location,
- const Map<string, string>& pairs,
- StateMachine* machine_ptr = NULL);
-
- // Destructor
- ~Type() {}
-
- // Public Methods
- string cIdent() const { return m_c_id; }
- string desc() const { return m_desc; }
-
- bool isPrimitive() const { return existPair("primitive"); }
- bool isNetworkMessage() const { return existPair("networkmessage"); }
- bool isMessage() const { return existPair("message"); }
- bool isBuffer() const { return existPair("buffer"); }
- bool isInPort() const { return existPair("inport"); }
- bool isOutPort() const { return existPair("outport"); }
- bool isEnumeration() const { return existPair("enumeration"); }
- bool isExternal() const { return existPair("external"); }
- bool isGlobal() const { return existPair("global"); }
- bool isInterface() const { return existPair("interface"); }
-
- // The data members of this type - only valid for messages and SLICC
- // declared structures
- // Return false on error
- bool dataMemberAdd(string id, Type* type_ptr, Map<string, string>& pairs,
- string* init_code);
- bool dataMemberExist(string id) const { return m_data_member_map.exist(id); }
- Type* dataMemberType(string id) const { return m_data_member_map.lookup(id); }
-
- // The methods of this type - only valid for external types
- // Return false on error
- bool methodAdd(string name, Type* return_type_ptr, const Vector<Type*>& param_type_vec);
- bool methodExist(string id) const { return m_method_return_type_map.exist(id); }
-
- string methodId(string name, const Vector<Type*>& param_type_vec);
- Type* methodReturnType(string id) const { return m_method_return_type_map.lookup(id); }
- const Vector<Type*>& methodParamType(string id) const { return m_method_param_type_map.lookup(id); }
-
- // The enumeration idents of this type - only valid for enums
- // Return false on error
- bool enumAdd(string id, Map<string, string> pairs);
- bool enumExist(string id) const { return m_enum_map.exist(id); }
-
- // Write the C output files
- void writeCFiles(string path) ;
-
- bool hasDefault() const { return existPair("default"); }
- string getDefault() const { return lookupPair("default"); }
-
- void print(ostream& out) const {}
-private:
- // Private Methods
-
- void printTypeH(string path) const;
- void printTypeC(string path) const;
- void printEnumC(string path) const;
- void printEnumH(string path) const;
-
- // Private copy constructor and assignment operator
- Type(const Type& obj);
- Type& operator=(const Type& obj);
-
- // Data Members (m_ prefix)
- string m_c_id;
- string m_desc;
-
- // Data Members
- Map<string, Type*> m_data_member_map;
- Vector<string> m_data_member_ident_vec;
- Vector<Type*> m_data_member_type_vec;
- Vector<Map<string, string> > m_data_member_pairs_vec;
- Vector<string*> m_data_member_init_code_vec;
- // Needs pairs here
-
- // Methods
- Map<string, Type*> m_method_return_type_map;
- Map<string, Vector<Type*> > m_method_param_type_map;
- // Needs pairs here
-
- // Enum
- Map<string, bool> m_enum_map;
- Vector<string> m_enum_vec;
- Vector< Map < string, string > > m_enum_pairs;
-
- // MachineType Hack
- bool m_isMachineType;
-
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const Type& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const Type& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //TYPE_H
diff --git a/src/mem/slicc/symbols/Type.py b/src/mem/slicc/symbols/Type.py
new file mode 100644
index 000000000..bafc6ea9e
--- /dev/null
+++ b/src/mem/slicc/symbols/Type.py
@@ -0,0 +1,652 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.util import code_formatter, orderdict
+
+from slicc.util import PairContainer
+from slicc.symbols.Symbol import Symbol
+
+class DataMember(PairContainer):
+ def __init__(self, ident, type, pairs, init_code):
+ super(DataMember, self).__init__(pairs)
+ self.ident = ident
+ self.type = type
+ self.init_code = init_code
+
+class Enumeration(PairContainer):
+ def __init__(self, ident, pairs):
+ super(Enumeration, self).__init__(pairs)
+ self.ident = ident
+
+class Method(object):
+ def __init__(self, return_type, param_types):
+ self.return_type = return_type
+ self.param_types = param_types
+
+class Type(Symbol):
+ def __init__(self, table, ident, location, pairs, machine=None):
+ super(Type, self).__init__(table, ident, location, pairs)
+ self.c_ident = ident
+ if machine:
+ if self.isExternal or self.isPrimitive:
+ if "external_name" in self:
+ self.c_ident = self["external_name"]
+ else:
+ # Append with machine name
+ self.c_ident = "%s_%s" % (machine, ident)
+
+ self.pairs.setdefault("desc", "No description avaliable")
+
+ # check for interface that this Type implements
+ if "interface" in self:
+ interface = self["interface"]
+ if interface in ("Message", "NetworkMessage"):
+ self["message"] = "yes"
+ if interface == "NetworkMessage":
+ self["networkmessage"] = "yes"
+
+ # FIXME - all of the following id comparisons are fragile hacks
+ if self.ident in ("CacheMemory", "NewCacheMemory",
+ "TLCCacheMemory", "DNUCACacheMemory",
+ "DNUCABankCacheMemory", "L2BankCacheMemory",
+ "CompressedCacheMemory", "PrefetchCacheMemory"):
+ self["cache"] = "yes"
+
+ if self.ident in ("TBETable", "DNUCATBETable", "DNUCAStopTable"):
+ self["tbe"] = "yes"
+
+ if self.ident == "NewTBETable":
+ self["newtbe"] = "yes"
+
+ if self.ident == "TimerTable":
+ self["timer"] = "yes"
+
+ if self.ident == "DirectoryMemory":
+ self["dir"] = "yes"
+
+ if self.ident == "PersistentTable":
+ self["persistent"] = "yes"
+
+ if self.ident == "Prefetcher":
+ self["prefetcher"] = "yes"
+
+ if self.ident == "DNUCA_Movement":
+ self["mover"] = "yes"
+
+ self.isMachineType = (ident == "MachineType")
+
+ self.data_members = orderdict()
+
+ # Methods
+ self.methods = {}
+
+ # Enums
+ self.enums = orderdict()
+
+ @property
+ def isPrimitive(self):
+ return "primitive" in self
+ @property
+ def isNetworkMessage(self):
+ return "networkmessage" in self
+ @property
+ def isMessage(self):
+ return "message" in self
+ @property
+ def isBuffer(self):
+ return "buffer" in self
+ @property
+ def isInPort(self):
+ return "inport" in self
+ @property
+ def isOutPort(self):
+ return "outport" in self
+ @property
+ def isEnumeration(self):
+ return "enumeration" in self
+ @property
+ def isExternal(self):
+ return "external" in self
+ @property
+ def isGlobal(self):
+ return "global" in self
+ @property
+ def isInterface(self):
+ return "interface" in self
+
+ # Return false on error
+ def dataMemberAdd(self, ident, type, pairs, init_code):
+ if ident in self.data_members:
+ return False
+
+ member = DataMember(ident, type, pairs, init_code)
+ self.data_members[ident] = member
+
+ return True
+
+ def dataMemberType(self, ident):
+ return self.data_members[ident].type
+
+ def methodId(self, name, param_type_vec):
+ return '_'.join([name] + [ pt.c_ident for pt in param_type_vec ])
+
+ def methodAdd(self, name, return_type, param_type_vec):
+ ident = self.methodId(name, param_type_vec)
+ if ident in self.methods:
+ return False
+
+ self.methods[ident] = Method(return_type, param_type_vec)
+ return True
+
+ def enumAdd(self, ident, pairs):
+ if ident in self.enums:
+ return False
+
+ self.enums[ident] = Enumeration(ident, pairs)
+
+ # Add default
+ if "default" not in self:
+ self["default"] = "%s_NUM" % self.c_ident
+
+ return True
+
+ def writeCodeFiles(self, path):
+ if self.isExternal:
+ # Do nothing
+ pass
+ elif self.isEnumeration:
+ self.printEnumHH(path)
+ self.printEnumCC(path)
+ else:
+ # User defined structs and messages
+ self.printTypeHH(path)
+ self.printTypeCC(path)
+
+ def printTypeHH(self, path):
+ code = code_formatter()
+ code('''
+/** \\file ${{self.c_ident}}.hh
+ *
+ *
+ * Auto generated C++ code started by $__file__:$__line__
+ */
+
+#ifndef ${{self.c_ident}}_H
+#define ${{self.c_ident}}_H
+
+#include "mem/ruby/common/Global.hh"
+#include "mem/gems_common/Allocator.hh"
+''')
+
+ for dm in self.data_members.values():
+ if not dm.type.isPrimitive:
+ code('#include "mem/protocol/$0.hh"', dm.type.c_ident)
+
+ parent = ""
+ if "interface" in self:
+ code('#include "mem/protocol/$0.hh"', self["interface"])
+ parent = " : public %s" % self["interface"]
+
+ code('''
+$klass ${{self.c_ident}}$parent {
+ public:
+ ${{self.c_ident}}()
+''', klass="class")
+
+ # Call superclass constructor
+ if "interface" in self:
+ code(' : ${{self["interface"]}}()')
+
+ code.indent()
+ code("{")
+ if not self.isGlobal:
+ code.indent()
+ for dm in self.data_members.values():
+ ident = dm.ident
+ if "default" in dm:
+ # look for default value
+ code('m_$ident = ${{dm["default"]}}; // default for this field')
+ elif "default" in dm.type:
+ # Look for the type default
+ tid = dm.type.c_ident
+ code('m_$ident = ${{dm.type["default"]}}; // default value of $tid')
+ else:
+ code('// m_$ident has no default')
+ code.dedent()
+ code('}')
+
+ # ******** Default destructor ********
+ code('~${{self.c_ident}}() { };')
+
+ # ******** Full init constructor ********
+ if not self.isGlobal:
+ params = [ 'const %s& local_%s' % (dm.type.c_ident, dm.ident) \
+ for dm in self.data_members.itervalues() ]
+
+ if self.isMessage:
+ params.append('const unsigned local_proc_id')
+
+ params = ', '.join(params)
+ code('${{self.c_ident}}($params)')
+
+ # Call superclass constructor
+ if "interface" in self:
+ code(' : ${{self["interface"]}}()')
+
+ code('{')
+ code.indent()
+ for dm in self.data_members.values():
+ code('m_${{dm.ident}} = local_${{dm.ident}};')
+ if "nextLineCallHack" in dm:
+ code('m_${{dm.ident}}${{dm["nextLineCallHack"]}};')
+
+ if self.isMessage:
+ code('proc_id = local_proc_id;')
+
+ code.dedent()
+ code('}')
+
+ # create a static factory method
+ if "interface" in self:
+ code('''
+static ${{self["interface"]}}* create() {
+ return new ${{self.c_ident}}();
+}
+''')
+
+ # ******** Message member functions ********
+ # FIXME: those should be moved into slicc file, slicc should
+ # support more of the c++ class inheritance
+
+ if self.isMessage:
+ code('''
+Message* clone() const { checkAllocator(); return s_allocator_ptr->allocate(*this); }
+void destroy() { checkAllocator(); s_allocator_ptr->deallocate(this); }
+static Allocator<${{self.c_ident}}>* s_allocator_ptr;
+static void checkAllocator() { if (s_allocator_ptr == NULL) { s_allocator_ptr = new Allocator<${{self.c_ident}}>; }}
+''')
+
+ if not self.isGlobal:
+ # const Get methods for each field
+ code('// Const accessors methods for each field')
+ for dm in self.data_members.values():
+ code('''
+/** \\brief Const accessor method for ${{dm.ident}} field.
+ * \\return ${{dm.ident}} field
+ */
+const ${{dm.type.c_ident}}& get${{dm.ident}}() const { return m_${{dm.ident}}; }
+''')
+
+ # Non-const Get methods for each field
+ code('// Non const Accessors methods for each field')
+ for dm in self.data_members.values():
+ code('''
+/** \\brief Non-const accessor method for ${{dm.ident}} field.
+ * \\return ${{dm.ident}} field
+ */
+${{dm.type.c_ident}}& get${{dm.ident}}() { return m_${{dm.ident}}; }
+''')
+
+ #Set methods for each field
+ code('// Mutator methods for each field')
+ for dm in self.data_members.values():
+ code('''
+/** \\brief Mutator method for ${{dm.ident}} field */
+void set${{dm.ident}}(const ${{dm.type.c_ident}}& local_${{dm.ident}}) { m_${{dm.ident}} = local_${{dm.ident}}; }
+''')
+
+ code('void print(ostream& out) const;')
+ code.dedent()
+ code(' //private:')
+ code.indent()
+
+ # Data members for each field
+ for dm in self.data_members.values():
+ if "abstract" not in dm:
+ const = ""
+ init = ""
+
+ # global structure
+ if self.isGlobal:
+ const = "static const "
+
+ # init value
+ if dm.init_code:
+ # only global structure can have init value here
+ assert self.isGlobal
+ init = " = %s" % (dm.init_code)
+
+ desc = ""
+ if "desc" in dm:
+ desc = '/**< %s */' % dm["desc"]
+
+ code('$const${{dm.type.c_ident}} m_${{dm.ident}}$init; $desc')
+
+ if self.isMessage:
+ code('unsigned proc_id;')
+
+ code.dedent()
+ code('};')
+
+ code('''
+// Output operator declaration
+ostream& operator<<(ostream& out, const ${{self.c_ident}}& obj);
+
+// Output operator definition
+extern inline
+ostream& operator<<(ostream& out, const ${{self.c_ident}}& obj)
+{
+ obj.print(out);
+ out << flush;
+ return out;
+}
+
+#endif // ${{self.c_ident}}_H
+''')
+
+ code.write(path, "%s.hh" % self.c_ident)
+
+ def printTypeCC(self, path):
+ code = code_formatter()
+
+ code('''
+/** \\file ${{self.c_ident}}.cc
+ *
+ * Auto generated C++ code started by $__file__:$__line__
+ */
+
+#include "mem/protocol/${{self.c_ident}}.hh"
+''')
+
+ if self.isMessage:
+ code('Allocator<${{self.c_ident}}>* ${{self.c_ident}}::s_allocator_ptr = NULL;')
+ code('''
+/** \\brief Print the state of this object */
+void ${{self.c_ident}}::print(ostream& out) const
+{
+ out << "[${{self.c_ident}}: ";
+''')
+
+ # For each field
+ code.indent()
+ for dm in self.data_members.values():
+ code('out << "${{dm.ident}} = " << m_${{dm.ident}} << " ";''')
+
+ if self.isMessage:
+ code('out << "Time = " << getTime() << " ";')
+ code.dedent()
+
+ # Trailer
+ code('''
+ out << "]";
+}''')
+
+ code.write(path, "%s.cc" % self.c_ident)
+
+ def printEnumHH(self, path):
+ code = code_formatter()
+ code('''
+/** \\file ${{self.c_ident}}.hh
+ *
+ * Auto generated C++ code started by $__file__:$__line__
+ */
+#ifndef ${{self.c_ident}}_H
+#define ${{self.c_ident}}_H
+
+#include "mem/ruby/common/Global.hh"
+
+/** \\enum ${{self.c_ident}}
+ * \\brief ${{self.desc}}
+ */
+enum ${{self.c_ident}} {
+ ${{self.c_ident}}_FIRST,
+''')
+
+ code.indent()
+ # For each field
+ for i,(ident,enum) in enumerate(self.enums.iteritems()):
+ desc = enum.get("desc", "No description avaliable")
+ if i == 0:
+ init = ' = %s_FIRST' % self.c_ident
+ else:
+ init = ''
+ code('${{self.c_ident}}_${{enum.ident}}$init, /**< $desc */')
+ code.dedent()
+ code('''
+ ${{self.c_ident}}_NUM
+};
+${{self.c_ident}} string_to_${{self.c_ident}}(const string& str);
+string ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj);
+${{self.c_ident}} &operator++(${{self.c_ident}} &e);
+''')
+
+ # MachineType hack used to set the base component id for each Machine
+ if self.isMachineType:
+ code('''
+int ${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj);
+MachineType ${{self.c_ident}}_from_base_level(int);
+int ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj);
+int ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj);
+''')
+
+ for enum in self.enums.itervalues():
+ code('#define MACHINETYPE_${{enum.ident}} 1')
+
+ # Trailer
+ code('''
+ostream& operator<<(ostream& out, const ${{self.c_ident}}& obj);
+
+#endif // ${{self.c_ident}}_H
+''')
+
+ code.write(path, "%s.hh" % self.c_ident)
+
+ def printEnumCC(self, path):
+ code = code_formatter()
+ code('''
+/** \\file ${{self.c_ident}}.hh
+ *
+ * Auto generated C++ code started by $__file__:$__line__
+ */
+
+#include "mem/protocol/${{self.c_ident}}.hh"
+
+''')
+
+ if self.isMachineType:
+ code('#include "mem/protocol/ControllerFactory.hh"')
+ for enum in self.enums.itervalues():
+ code('#include "mem/protocol/${{enum.ident}}_Controller.hh"')
+
+ code('''
+ostream& operator<<(ostream& out, const ${{self.c_ident}}& obj)
+{
+ out << ${{self.c_ident}}_to_string(obj);
+ out << flush;
+ return out;
+}
+
+string ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj)
+{
+ switch(obj) {
+''')
+
+ # For each field
+ code.indent()
+ for enum in self.enums.itervalues():
+ code(' case ${{self.c_ident}}_${{enum.ident}}:')
+ code(' return "${{enum.ident}}";')
+ code.dedent()
+
+ # Trailer
+ code('''
+ default:
+ ERROR_MSG("Invalid range for type ${{self.c_ident}}");
+ return "";
+ }
+}
+
+${{self.c_ident}} string_to_${{self.c_ident}}(const string& str)
+{
+''')
+
+ # For each field
+ code.indent()
+ code("if (false) {")
+ start = "} else "
+ for enum in self.enums.itervalues():
+ code('${start}if (str == "${{enum.ident}}") {')
+ code(' return ${{self.c_ident}}_${{enum.ident}};')
+ code.dedent()
+
+ code('''
+ } else {
+ WARN_EXPR(str);
+ ERROR_MSG("Invalid string conversion for type ${{self.c_ident}}");
+ }
+}
+
+${{self.c_ident}}& operator++(${{self.c_ident}}& e) {
+ assert(e < ${{self.c_ident}}_NUM);
+ return e = ${{self.c_ident}}(e+1);
+}
+''')
+
+ # MachineType hack used to set the base level and number of
+ # components for each Machine
+ if self.isMachineType:
+ code('''
+/** \\brief returns the base vector index for each machine type to be used by NetDest
+ *
+ * \\return the base vector index for each machine type to be used by NetDest
+ * \\see NetDest.hh
+ */
+int ${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj)
+{
+ switch(obj) {
+''')
+
+ # For each field
+ code.indent()
+ for i,enum in enumerate(self.enums.itervalues()):
+ code(' case ${{self.c_ident}}_${{enum.ident}}:')
+ code(' return $i;')
+ code.dedent()
+
+ # total num
+ code('''
+ case ${{self.c_ident}}_NUM:
+ return ${{len(self.enums)}};
+
+ default:
+ ERROR_MSG("Invalid range for type ${{self.c_ident}}");
+ return -1;
+ }
+}
+
+/** \\brief returns the machine type for each base vector index used by NetDest
+ *
+ * \\return the MachineTYpe
+ */
+MachineType ${{self.c_ident}}_from_base_level(int type)
+{
+ switch(type) {
+''')
+
+ # For each field
+ code.indent()
+ for i,enum in enumerate(self.enums.itervalues()):
+ code(' case $i:')
+ code(' return ${{self.c_ident}}_${{enum.ident}};')
+ code.dedent()
+
+ # Trailer
+ code('''
+ default:
+ ERROR_MSG("Invalid range for type ${{self.c_ident}}");
+ return MachineType_NUM;
+ }
+}
+
+/** \\brief The return value indicates the number of components created
+ * before a particular machine\'s components
+ *
+ * \\return the base number of components for each machine
+ */
+int ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj)
+{
+ int base = 0;
+ switch(obj) {
+''')
+
+ # For each field
+ code.indent()
+ code(' case ${{self.c_ident}}_NUM:')
+ for enum in reversed(self.enums.values()):
+ code(' base += ${{enum.ident}}_Controller::getNumControllers();')
+ code(' case ${{self.c_ident}}_${{enum.ident}}:')
+ code(' break;')
+ code.dedent()
+
+ code('''
+ default:
+ ERROR_MSG("Invalid range for type ${{self.c_ident}}");
+ return -1;
+ }
+
+ return base;
+}
+
+/** \\brief returns the total number of components for each machine
+ * \\return the total number of components for each machine
+ */
+int ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj)
+{
+ switch(obj) {
+''')
+
+ # For each field
+ for enum in self.enums.itervalues():
+ code('''
+ case ${{self.c_ident}}_${{enum.ident}}:
+ return ${{enum.ident}}_Controller::getNumControllers();
+''')
+
+ # total num
+ code('''
+ case ${{self.c_ident}}_NUM:
+ default:
+ ERROR_MSG("Invalid range for type ${{self.c_ident}}");
+ return -1;
+ }
+}
+''')
+
+ # Write the file
+ code.write(path, "%s.cc" % self.c_ident)
+
+__all__ = [ "Type" ]
diff --git a/src/mem/slicc/symbols/Var.hh b/src/mem/slicc/symbols/Var.hh
deleted file mode 100644
index 4cb504296..000000000
--- a/src/mem/slicc/symbols/Var.hh
+++ /dev/null
@@ -1,98 +0,0 @@
-
-/*
- * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Var.hh
- *
- * Description:
- *
- * $Id$
- *
- * */
-
-#ifndef VAR_H
-#define VAR_H
-
-#include "mem/slicc/slicc_global.hh"
-#include "mem/slicc/symbols/Symbol.hh"
-#include "mem/slicc/symbols/Type.hh"
-
-class StateMachine;
-
-class Var : public Symbol {
-public:
- // Constructors
- Var(string id, const Location& location,
- Type* type_ptr, string code,
- const Map<string, string>& pairs,
- StateMachine* machine_ptr = NULL);
-
- // Var(string id, const Location& location,
- // Type* type_ptr, string code) : Symbol(id, location) { m_type_ptr = type_ptr; m_code = code; }
-
- // Destructor
- ~Var() {}
-
- // Public Methods
- string cIdent() const { return m_c_id; }
- void writeCFiles(string path) {}
- string getCode() const { return m_code; }
- Type* getType() const { return m_type_ptr; }
- StateMachine* getMachine() const { return m_machine_ptr; }
-
- void print(ostream& out) const;
-private:
- // Private Methods
-
- // Private copy constructor and assignment operator
- Var(const Var& obj);
- Var& operator=(const Var& obj);
-
- // Data Members (m_ prefix)
- string m_c_id;
- Type* m_type_ptr;
- string m_code;
- StateMachine* m_machine_ptr;
-};
-
-// Output operator declaration
-ostream& operator<<(ostream& out, const Var& obj);
-
-// ******************* Definitions *******************
-
-// Output operator definition
-extern inline
-ostream& operator<<(ostream& out, const Var& obj)
-{
- obj.print(out);
- out << flush;
- return out;
-}
-
-#endif //VAR_H
diff --git a/src/mem/slicc/symbols/Var.py b/src/mem/slicc/symbols/Var.py
new file mode 100644
index 000000000..87a101f65
--- /dev/null
+++ b/src/mem/slicc/symbols/Var.py
@@ -0,0 +1,50 @@
+# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from slicc.symbols.Symbol import Symbol
+
+class Var(Symbol):
+ def __init__(self, symtab, ident, location, type, code, pairs,
+ machine=None):
+ super(Var, self).__init__(symtab, ident, location, pairs)
+
+ if machine:
+ self.c_ident = "%s_%s" % (machine, ident)
+ else:
+ self.c_ident = ident
+
+ self.machine = machine
+ self.type = type
+ self.code = code
+
+ def __repr__(self):
+ return "[Var id: %s]" % (self.c_ident)
+
+ def writeCodeFiles(self, path):
+ pass
+
+__all__ = [ "Var" ]
diff --git a/src/mem/slicc/symbols/__init__.py b/src/mem/slicc/symbols/__init__.py
new file mode 100644
index 000000000..43388a5fe
--- /dev/null
+++ b/src/mem/slicc/symbols/__init__.py
@@ -0,0 +1,38 @@
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Nathan Binkert
+
+from slicc.symbols.Action import Action
+from slicc.symbols.Event import Event
+from slicc.symbols.Func import Func
+from slicc.symbols.State import State
+from slicc.symbols.StateMachine import StateMachine
+from slicc.symbols.Symbol import Symbol
+from slicc.symbols.SymbolTable import SymbolTable
+from slicc.symbols.Transition import Transition
+from slicc.symbols.Type import Type
+from slicc.symbols.Var import Var
diff --git a/src/mem/slicc/util.py b/src/mem/slicc/util.py
new file mode 100644
index 000000000..abadc3e30
--- /dev/null
+++ b/src/mem/slicc/util.py
@@ -0,0 +1,75 @@
+# Copyright (c) 2009 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import os
+import sys
+
+def makeDir(path):
+ if os.path.exists(path):
+ if not os.path.isdir(path):
+ raise AttributeError, "%s exists but is not directory" % path
+ else:
+ os.mkdir(path)
+
+class PairContainer(object):
+ def __init__(self, pairs=None):
+ self.pairs = {}
+ if pairs:
+ self.pairs.update(pairs)
+
+ def __contains__(self, item):
+ return item in self.pairs
+
+ def __getitem__(self, item):
+ return self.pairs[item]
+
+ def __setitem__(self, item, value):
+ self.pairs[item] = value
+
+ def get(self, item, failobj=None):
+ return self.pairs.get(item, failobj)
+
+class Location(object):
+ def __init__(self, filename, lineno):
+ self.filename = filename
+ self.lineno = lineno
+
+ def __str__(self):
+ return '%s:%d' % (os.path.basename(self.filename), self.lineno)
+
+ def warning(self, message, *args):
+ if args:
+ message = message % args
+ #raise Exception, "%s: Warning: %s" % (self, message)
+ print >>sys.stderr, "%s: Warning: %s" % (self, message)
+
+ def error(self, message, *args):
+ if args:
+ message = message % args
+ raise Exception, "%s: Error: %s" % (self, message)
+ sys.exit("\n%s: Error: %s" % (self, message))
+
+__all__ = [ 'makeDir', 'PairContainer', 'Location' ]
diff --git a/src/mem/translating_port.cc b/src/mem/translating_port.cc
index 54de6625e..700229b23 100644
--- a/src/mem/translating_port.cc
+++ b/src/mem/translating_port.cc
@@ -30,7 +30,9 @@
*/
#include <string>
+
#include "base/chunk_generator.hh"
+#include "config/the_isa.hh"
#include "mem/port.hh"
#include "mem/translating_port.hh"
#include "mem/page_table.hh"
diff --git a/src/mem/vport.cc b/src/mem/vport.cc
index 15be45c2a..ab061c019 100644
--- a/src/mem/vport.cc
+++ b/src/mem/vport.cc
@@ -34,6 +34,7 @@
*/
#include "base/chunk_generator.hh"
+#include "config/the_isa.hh"
#include "cpu/thread_context.hh"
#include "mem/vport.hh"
diff --git a/src/python/SConscript b/src/python/SConscript
index bb892f376..935986a12 100644
--- a/src/python/SConscript
+++ b/src/python/SConscript
@@ -38,7 +38,6 @@ PySource('', 'importer.py')
PySource('m5', 'm5/__init__.py')
PySource('m5', 'm5/SimObject.py')
PySource('m5', 'm5/config.py')
-PySource('m5', 'm5/convert.py')
PySource('m5', 'm5/core.py')
PySource('m5', 'm5/debug.py')
PySource('m5', 'm5/event.py')
@@ -47,18 +46,18 @@ PySource('m5', 'm5/options.py')
PySource('m5', 'm5/params.py')
PySource('m5', 'm5/proxy.py')
PySource('m5', 'm5/simulate.py')
-PySource('m5', 'm5/smartdict.py')
PySource('m5', 'm5/stats.py')
PySource('m5', 'm5/ticks.py')
PySource('m5', 'm5/trace.py')
PySource('m5.util', 'm5/util/__init__.py')
PySource('m5.util', 'm5/util/attrdict.py')
PySource('m5.util', 'm5/util/code_formatter.py')
+PySource('m5.util', 'm5/util/convert.py')
PySource('m5.util', 'm5/util/grammar.py')
PySource('m5.util', 'm5/util/jobfile.py')
-PySource('m5.util', 'm5/util/misc.py')
PySource('m5.util', 'm5/util/multidict.py')
PySource('m5.util', 'm5/util/orderdict.py')
+PySource('m5.util', 'm5/util/smartdict.py')
SwigSource('m5.internal', 'swig/core.i')
SwigSource('m5.internal', 'swig/debug.i')
diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py
index 8ef22be4e..0e0ffaea9 100644
--- a/src/python/m5/SimObject.py
+++ b/src/python/m5/SimObject.py
@@ -31,47 +31,24 @@ import math
import sys
import types
-import proxy
-import m5
-from util import *
-
-# These utility functions have to come first because they're
-# referenced in params.py... otherwise they won't be defined when we
-# import params below, and the recursive import of this file from
-# params.py will not find these names.
-def isSimObject(value):
- return isinstance(value, SimObject)
-
-def isSimObjectClass(value):
- return issubclass(value, SimObject)
-
-def isSimObjectSequence(value):
- if not isinstance(value, (list, tuple)) or len(value) == 0:
- return False
-
- for val in value:
- if not isNullPointer(val) and not isSimObject(val):
- return False
-
- return True
+try:
+ import pydot
+except:
+ pydot = False
-def isSimObjectOrSequence(value):
- return isSimObject(value) or isSimObjectSequence(value)
+import m5
+from m5.util import *
# Have to import params up top since Param is referenced on initial
# load (when SimObject class references Param to create a class
# variable, the 'name' param)...
-from params import *
+from m5.params import *
# There are a few things we need that aren't in params.__all__ since
# normal users don't need them
-from params import ParamDesc, VectorParamDesc, isNullPointer, SimObjVector
-from proxy import *
+from m5.params import ParamDesc, VectorParamDesc, isNullPointer, SimObjVector
-noDot = False
-try:
- import pydot
-except:
- noDot = True
+from m5.proxy import *
+from m5.proxy import isproxy
#####################################################################
#
@@ -141,7 +118,7 @@ class MetaSimObject(type):
# and only allow "private" attributes to be passed to the base
# __new__ (starting with underscore).
def __new__(mcls, name, bases, dict):
- assert name not in allClasses
+ assert name not in allClasses, "SimObject %s already present" % name
# Copy "private" attributes, functions, and classes to the
# official dict. Everything else goes in _init_dict to be
@@ -678,7 +655,7 @@ class SimObject(object):
def unproxy_all(self):
for param in self._params.iterkeys():
value = self._values.get(param)
- if value != None and proxy.isproxy(value):
+ if value != None and isproxy(value):
try:
value = value.unproxy(self)
except:
@@ -749,8 +726,8 @@ class SimObject(object):
for param in param_names:
value = self._values.get(param)
if value is None:
- m5.fatal("%s.%s without default or user set value",
- self.path(), param)
+ fatal("%s.%s without default or user set value",
+ self.path(), param)
value = value.getValue()
if isinstance(self._params[param], VectorParamDesc):
@@ -886,6 +863,34 @@ def resolveSimObject(name):
obj = instanceDict[name]
return obj.getCCObject()
+def isSimObject(value):
+ return isinstance(value, SimObject)
+
+def isSimObjectClass(value):
+ return issubclass(value, SimObject)
+
+def isSimObjectSequence(value):
+ if not isinstance(value, (list, tuple)) or len(value) == 0:
+ return False
+
+ for val in value:
+ if not isNullPointer(val) and not isSimObject(val):
+ return False
+
+ return True
+
+def isSimObjectOrSequence(value):
+ return isSimObject(value) or isSimObjectSequence(value)
+
+baseClasses = allClasses.copy()
+baseInstances = instanceDict.copy()
+
+def clear():
+ global allClasses, instanceDict
+
+ allClasses = baseClasses.copy()
+ instanceDict = baseInstances.copy()
+
# __all__ defines the list of symbols that get exported when
# 'from config import *' is invoked. Try to keep this reasonably
# short to avoid polluting other namespaces.
diff --git a/src/python/m5/__init__.py b/src/python/m5/__init__.py
index c3512cd0d..9f9459ae8 100644
--- a/src/python/m5/__init__.py
+++ b/src/python/m5/__init__.py
@@ -25,106 +25,24 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Nathan Binkert
-# Steve Reinhardt
-import os
-import sys
+# Import useful subpackages of M5, but *only* when run as an m5
+# script. This is mostly to keep backward compatibility with existing
+# scripts while allowing new SCons code to operate properly.
-import smartdict
-
-# define a MaxTick parameter
-MaxTick = 2**63 - 1
-
-# define this here so we can use it right away if necessary
-
-def errorURL(prefix, s):
- try:
- import zlib
- hashstr = "%x" % zlib.crc32(s)
- except:
- hashstr = "UnableToHash"
- return "For more information see: http://www.m5sim.org/%s/%s" % \
- (prefix, hashstr)
-
-
-# panic() should be called when something happens that should never
-# ever happen regardless of what the user does (i.e., an acutal m5
-# bug).
-def panic(fmt, *args):
- print >>sys.stderr, 'panic:', fmt % args
- print >>sys.stderr, errorURL('panic',fmt)
- sys.exit(1)
-
-# fatal() should be called when the simulation cannot continue due to
-# some condition that is the user's fault (bad configuration, invalid
-# arguments, etc.) and not a simulator bug.
-def fatal(fmt, *args):
- print >>sys.stderr, 'fatal:', fmt % args
- print >>sys.stderr, errorURL('fatal',fmt)
- sys.exit(1)
-
-# force scalars to one-element lists for uniformity
-def makeList(objOrList):
- if isinstance(objOrList, list):
- return objOrList
- return [objOrList]
-
-# Prepend given directory to system module search path. We may not
-# need this anymore if we can structure our config library more like a
-# Python package.
-def AddToPath(path):
- # if it's a relative path and we know what directory the current
- # python script is in, make the path relative to that directory.
- if not os.path.isabs(path) and sys.path[0]:
- path = os.path.join(sys.path[0], path)
- path = os.path.realpath(path)
- # sys.path[0] should always refer to the current script's directory,
- # so place the new dir right after that.
- sys.path.insert(1, path)
-
-# make a SmartDict out of the build options for our local use
-build_env = smartdict.SmartDict()
-
-# make a SmartDict out of the OS environment too
-env = smartdict.SmartDict()
-env.update(os.environ)
-
-# Since we have so many mutual imports in this package, we should:
-# 1. Put all intra-package imports at the *bottom* of the file, unless
-# they're absolutely needed before that (for top-level statements
-# or class attributes). Imports of "trivial" packages that don't
-# import other packages (e.g., 'smartdict') can be at the top.
-# 2. Never use 'from foo import *' on an intra-package import since
-# you can get the wrong result if foo is only partially imported
-# at the point you do that (i.e., because foo is in the middle of
-# importing *you*).
try:
import internal
except ImportError:
internal = None
-try:
- import defines
- build_env.update(defines.buildEnv)
-except ImportError:
- defines = None
-
if internal:
- defines.compileDate = internal.core.compileDate
- for k,v in internal.core.__dict__.iteritems():
- if k.startswith('flag_'):
- setattr(defines, k[5:], v)
+ import SimObject
+ import core
+ import objects
+ import params
+ import stats
+ import util
from event import *
- from simulate import *
from main import options, main
- import stats
- import core
-
-import SimObject
-import params
-
-try:
- import objects
-except ImportError:
- objects = None
+ from simulate import *
diff --git a/src/python/m5/main.py b/src/python/m5/main.py
index 2a308ff09..29f8cc976 100644
--- a/src/python/m5/main.py
+++ b/src/python/m5/main.py
@@ -32,7 +32,7 @@ import os
import socket
import sys
-from util import attrdict
+from util import attrdict, fatal
import config
from options import OptionParser
diff --git a/src/python/m5/params.py b/src/python/m5/params.py
index edd78fa28..cf64070c5 100644
--- a/src/python/m5/params.py
+++ b/src/python/m5/params.py
@@ -50,13 +50,10 @@ import re
import sys
import time
-import convert
import proxy
import ticks
from util import *
-import SimObject
-
def isSimObject(*args, **kwargs):
return SimObject.isSimObject(*args, **kwargs)
@@ -96,6 +93,8 @@ class ParamValue(object):
# Regular parameter description.
class ParamDesc(object):
+ file_ext = 'ptype'
+
def __init__(self, ptype_str, ptype, *args, **kwargs):
self.ptype_str = ptype_str
# remember ptype only if it is provided
@@ -130,7 +129,7 @@ class ParamDesc(object):
def __getattr__(self, attr):
if attr == 'ptype':
ptype = SimObject.allClasses[self.ptype_str]
- assert issubclass(ptype, SimObject.SimObject)
+ assert isSimObjectClass(ptype)
self.ptype = ptype
return ptype
@@ -185,6 +184,8 @@ class SimObjVector(VectorParamValue):
v.print_ini(ini_file)
class VectorParamDesc(ParamDesc):
+ file_ext = 'vptype'
+
# Convert assigned value to appropriate type. If the RHS is not a
# list or tuple, it generates a single-element list.
def convert(self, value):
@@ -711,32 +712,31 @@ class MetaEnum(MetaParamValue):
super(MetaEnum, cls).__init__(name, bases, init_dict)
- def __str__(cls):
- return cls.__name__
-
# Generate C++ class declaration for this enum type.
# Note that we wrap the enum in a class/struct to act as a namespace,
# so that the enum strings can be brief w/o worrying about collisions.
def cxx_decl(cls):
- code = "#ifndef __ENUM__%s\n" % cls
- code += '#define __ENUM__%s\n' % cls
+ name = cls.__name__
+ code = "#ifndef __ENUM__%s\n" % name
+ code += '#define __ENUM__%s\n' % name
code += '\n'
code += 'namespace Enums {\n'
- code += ' enum %s {\n' % cls
+ code += ' enum %s {\n' % name
for val in cls.vals:
code += ' %s = %d,\n' % (val, cls.map[val])
- code += ' Num_%s = %d,\n' % (cls, len(cls.vals))
+ code += ' Num_%s = %d,\n' % (name, len(cls.vals))
code += ' };\n'
- code += ' extern const char *%sStrings[Num_%s];\n' % (cls, cls)
+ code += ' extern const char *%sStrings[Num_%s];\n' % (name, name)
code += '}\n'
code += '\n'
code += '#endif\n'
return code
def cxx_def(cls):
- code = '#include "enums/%s.hh"\n' % cls
+ name = cls.__name__
+ code = '#include "enums/%s.hh"\n' % name
code += 'namespace Enums {\n'
- code += ' const char *%sStrings[Num_%s] =\n' % (cls, cls)
+ code += ' const char *%sStrings[Num_%s] =\n' % (name, name)
code += ' {\n'
for val in cls.vals:
code += ' "%s",\n' % val
@@ -1170,6 +1170,15 @@ class PortParamDesc(object):
ptype_str = 'Port'
ptype = Port
+baseEnums = allEnums.copy()
+baseParams = allParams.copy()
+
+def clear():
+ global allEnums, allParams
+
+ allEnums = baseEnums.copy()
+ allParams = baseParams.copy()
+
__all__ = ['Param', 'VectorParam',
'Enum', 'Bool', 'String', 'Float',
'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16',
@@ -1184,3 +1193,5 @@ __all__ = ['Param', 'VectorParam',
'Time',
'NextEthernetAddr', 'NULL',
'Port', 'VectorPort']
+
+import SimObject
diff --git a/src/python/m5/simulate.py b/src/python/m5/simulate.py
index 45992fe85..092bd0339 100644
--- a/src/python/m5/simulate.py
+++ b/src/python/m5/simulate.py
@@ -40,6 +40,9 @@ import SimObject
import ticks
import objects
+# define a MaxTick parameter
+MaxTick = 2**63 - 1
+
# The final hook to generate .ini files. Called from the user script
# once the config is built.
def instantiate(root):
diff --git a/src/python/m5/ticks.py b/src/python/m5/ticks.py
index 91834c9c8..181a65eba 100644
--- a/src/python/m5/ticks.py
+++ b/src/python/m5/ticks.py
@@ -41,7 +41,7 @@ def fixGlobalFrequency():
print "Global frequency set at %d ticks per second" % int(tps)
def setGlobalFrequency(ticksPerSecond):
- import convert
+ from m5.util import convert
global tps, tps_fixed
diff --git a/src/python/m5/trace.py b/src/python/m5/trace.py
index 17aa6196c..db239040a 100644
--- a/src/python/m5/trace.py
+++ b/src/python/m5/trace.py
@@ -48,5 +48,5 @@ def help():
if flag == 'All':
continue
print " %s: %s" % (flag, flags.descriptions[flag])
- util.print_list(flags.compoundMap[flag], indent=8)
+ util.printList(flags.compoundMap[flag], indent=8)
print
diff --git a/src/python/m5/util/__init__.py b/src/python/m5/util/__init__.py
index 3930c8b6f..7a674dd2d 100644
--- a/src/python/m5/util/__init__.py
+++ b/src/python/m5/util/__init__.py
@@ -1,4 +1,5 @@
-# Copyright (c) 2008 The Hewlett-Packard Development Company
+# Copyright (c) 2008-2009 The Hewlett-Packard Development Company
+# Copyright (c) 2004-2006 The Regents of The University of Michigan
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -26,14 +27,130 @@
#
# Authors: Nathan Binkert
+import os
+import re
+import sys
+
+import convert
+import jobfile
+
from attrdict import attrdict, optiondict
from code_formatter import code_formatter
-from misc import *
from multidict import multidict
from orderdict import orderdict
-import jobfile
+from smartdict import SmartDict
+
+# define this here so we can use it right away if necessary
+def errorURL(prefix, s):
+ try:
+ import zlib
+ hashstr = "%x" % zlib.crc32(s)
+ except:
+ hashstr = "UnableToHash"
+ return "For more information see: http://www.m5sim.org/%s/%s" % \
+ (prefix, hashstr)
+
+# panic() should be called when something happens that should never
+# ever happen regardless of what the user does (i.e., an acutal m5
+# bug).
+def panic(fmt, *args):
+ print >>sys.stderr, 'panic:', fmt % args
+ print >>sys.stderr, errorURL('panic',fmt)
+ sys.exit(1)
+
+# fatal() should be called when the simulation cannot continue due to
+# some condition that is the user's fault (bad configuration, invalid
+# arguments, etc.) and not a simulator bug.
+def fatal(fmt, *args):
+ print >>sys.stderr, 'fatal:', fmt % args
+ print >>sys.stderr, errorURL('fatal',fmt)
+ sys.exit(1)
+
+class Singleton(type):
+ def __call__(cls, *args, **kwargs):
+ if hasattr(cls, '_instance'):
+ return cls._instance
+
+ cls._instance = super(Singleton, cls).__call__(*args, **kwargs)
+ return cls._instance
+
+def addToPath(path):
+ """Prepend given directory to system module search path. We may not
+ need this anymore if we can structure our config library more like a
+ Python package."""
+
+ # if it's a relative path and we know what directory the current
+ # python script is in, make the path relative to that directory.
+ if not os.path.isabs(path) and sys.path[0]:
+ path = os.path.join(sys.path[0], path)
+ path = os.path.realpath(path)
+ # sys.path[0] should always refer to the current script's directory,
+ # so place the new dir right after that.
+ sys.path.insert(1, path)
+
+# Apply method to object.
+# applyMethod(obj, 'meth', <args>) is equivalent to obj.meth(<args>)
+def applyMethod(obj, meth, *args, **kwargs):
+ return getattr(obj, meth)(*args, **kwargs)
-def print_list(items, indent=4):
+# If the first argument is an (non-sequence) object, apply the named
+# method with the given arguments. If the first argument is a
+# sequence, apply the method to each element of the sequence (a la
+# 'map').
+def applyOrMap(objOrSeq, meth, *args, **kwargs):
+ if not isinstance(objOrSeq, (list, tuple)):
+ return applyMethod(objOrSeq, meth, *args, **kwargs)
+ else:
+ return [applyMethod(o, meth, *args, **kwargs) for o in objOrSeq]
+
+def compareVersions(v1, v2):
+ """helper function: compare arrays or strings of version numbers.
+ E.g., compare_version((1,3,25), (1,4,1)')
+ returns -1, 0, 1 if v1 is <, ==, > v2
+ """
+ def make_version_list(v):
+ if isinstance(v, (list,tuple)):
+ return v
+ elif isinstance(v, str):
+ return map(lambda x: int(re.match('\d+', x).group()), v.split('.'))
+ else:
+ raise TypeError
+
+ v1 = make_version_list(v1)
+ v2 = make_version_list(v2)
+ # Compare corresponding elements of lists
+ for n1,n2 in zip(v1, v2):
+ if n1 < n2: return -1
+ if n1 > n2: return 1
+ # all corresponding values are equal... see if one has extra values
+ if len(v1) < len(v2): return -1
+ if len(v1) > len(v2): return 1
+ return 0
+
+def crossproduct(items):
+ if len(items) == 1:
+ for i in items[0]:
+ yield (i,)
+ else:
+ for i in items[0]:
+ for j in crossproduct(items[1:]):
+ yield (i,) + j
+
+def flatten(items):
+ while items:
+ item = items.pop(0)
+ if isinstance(item, (list, tuple)):
+ items[0:0] = item
+ else:
+ yield item
+
+# force scalars to one-element lists for uniformity
+def makeList(objOrList):
+ if isinstance(objOrList, list):
+ return objOrList
+ return [objOrList]
+
+def printList(items, indent=4):
line = ' ' * indent
for i,item in enumerate(items):
if len(line) + len(item) > 76:
@@ -45,3 +162,27 @@ def print_list(items, indent=4):
else:
line += item
print line
+
+def readCommand(cmd, **kwargs):
+ """run the command cmd, read the results and return them
+ this is sorta like `cmd` in shell"""
+ from subprocess import Popen, PIPE, STDOUT
+
+ if isinstance(cmd, str):
+ cmd = cmd.split()
+
+ no_exception = 'exception' in kwargs
+ exception = kwargs.pop('exception', None)
+
+ kwargs.setdefault('shell', False)
+ kwargs.setdefault('stdout', PIPE)
+ kwargs.setdefault('stderr', STDOUT)
+ kwargs.setdefault('close_fds', True)
+ try:
+ subp = Popen(cmd, **kwargs)
+ except Exception, e:
+ if no_exception:
+ return exception
+ raise
+
+ return subp.communicate()[0]
diff --git a/src/python/m5/util/attrdict.py b/src/python/m5/util/attrdict.py
index 0b30258b9..8f7d59698 100644
--- a/src/python/m5/util/attrdict.py
+++ b/src/python/m5/util/attrdict.py
@@ -45,6 +45,12 @@ class attrdict(dict):
return self.__delitem__(attr)
return super(attrdict, self).__delattr__(attr)
+ def __getstate__(self):
+ return dict(self)
+
+ def __setstate__(self, state):
+ self.update(state)
+
class multiattrdict(attrdict):
"""Wrap attrdict so that nested attribute accesses automatically create
nested dictionaries."""
@@ -52,7 +58,7 @@ class multiattrdict(attrdict):
try:
return super(multiattrdict, self).__getattr__(attr)
except AttributeError:
- d = optiondict()
+ d = multiattrdict()
setattr(self, attr, d)
return d
@@ -80,8 +86,12 @@ if __name__ == '__main__':
print dir(x)
print(x)
+ print
+ print "multiattrdict"
x = multiattrdict()
+ x.x.x.x = 9
x.y.z = 9
print x
print x.y
print x.y.z
+ print x.z.z
diff --git a/src/python/m5/util/code_formatter.py b/src/python/m5/util/code_formatter.py
index 919a6423b..396fe0e52 100644
--- a/src/python/m5/util/code_formatter.py
+++ b/src/python/m5/util/code_formatter.py
@@ -24,6 +24,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+import __builtin__
import inspect
import os
import re
@@ -64,8 +65,8 @@ class lookup(object):
if self.formatter.globals and item in self.frame.f_globals:
return self.frame.f_globals[item]
- if item in __builtins__:
- return __builtins__[item]
+ if item in __builtin__.__dict__:
+ return __builtin__.__dict__[item]
try:
item = int(item)
diff --git a/src/python/m5/convert.py b/src/python/m5/util/convert.py
index bb9e3e1f1..bb9e3e1f1 100644
--- a/src/python/m5/convert.py
+++ b/src/python/m5/util/convert.py
diff --git a/src/python/m5/util/grammar.py b/src/python/m5/util/grammar.py
index 93c2c84c4..ab5f35868 100644
--- a/src/python/m5/util/grammar.py
+++ b/src/python/m5/util/grammar.py
@@ -55,6 +55,7 @@ class Tokenizer(object):
break
yield tok
self.input = _input()
+ self.lexer = lexer
def next(self):
return self.input.next()
@@ -68,6 +69,9 @@ class Tokenizer(object):
except StopIteration:
return None
+ def __getattr__(self, attr):
+ return getattr(self.lexer, attr)
+
class Grammar(object):
def __init__(self, output=None, debug=False):
self.yacc_args = {}
diff --git a/src/python/m5/util/jobfile.py b/src/python/m5/util/jobfile.py
index c830895f6..9c59778e5 100644
--- a/src/python/m5/util/jobfile.py
+++ b/src/python/m5/util/jobfile.py
@@ -28,9 +28,6 @@
import sys
-from attrdict import optiondict
-from misc import crossproduct
-
class Data(object):
def __init__(self, name, desc, **kwargs):
self.name = name
@@ -108,7 +105,8 @@ class Data(object):
yield key
def optiondict(self):
- result = optiondict()
+ import m5.util
+ result = m5.util.optiondict()
for key in self:
result[key] = self[key]
return result
@@ -328,7 +326,9 @@ class Configuration(Data):
optgroups = [ g.subopts() for g in groups ]
if not optgroups:
return
- for options in crossproduct(optgroups):
+
+ import m5.util
+ for options in m5.util.crossproduct(optgroups):
for opt in options:
cpt = opt._group._checkpoint
if not isinstance(cpt, bool) and cpt != opt:
diff --git a/src/python/m5/util/misc.py b/src/python/m5/util/misc.py
deleted file mode 100644
index 094e3ed9a..000000000
--- a/src/python/m5/util/misc.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright (c) 2004-2006 The Regents of The University of Michigan
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met: redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer;
-# redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution;
-# neither the name of the copyright holders nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# Authors: Steve Reinhardt
-# Nathan Binkert
-
-#############################
-#
-# Utility classes & methods
-#
-#############################
-
-class Singleton(type):
- def __call__(cls, *args, **kwargs):
- if hasattr(cls, '_instance'):
- return cls._instance
-
- cls._instance = super(Singleton, cls).__call__(*args, **kwargs)
- return cls._instance
-
-# Apply method to object.
-# applyMethod(obj, 'meth', <args>) is equivalent to obj.meth(<args>)
-def applyMethod(obj, meth, *args, **kwargs):
- return getattr(obj, meth)(*args, **kwargs)
-
-# If the first argument is an (non-sequence) object, apply the named
-# method with the given arguments. If the first argument is a
-# sequence, apply the method to each element of the sequence (a la
-# 'map').
-def applyOrMap(objOrSeq, meth, *args, **kwargs):
- if not isinstance(objOrSeq, (list, tuple)):
- return applyMethod(objOrSeq, meth, *args, **kwargs)
- else:
- return [applyMethod(o, meth, *args, **kwargs) for o in objOrSeq]
-
-def crossproduct(items):
- if not isinstance(items, (list, tuple)):
- raise AttributeError, 'crossproduct works only on sequences'
-
- if not items:
- yield None
- return
-
- current = items[0]
- remainder = items[1:]
-
- if not hasattr(current, '__iter__'):
- current = [ current ]
-
- for item in current:
- for rem in crossproduct(remainder):
- data = [ item ]
- if rem:
- data += rem
- yield data
-
-def flatten(items):
- if not isinstance(items, (list, tuple)):
- yield items
- return
-
- for item in items:
- for flat in flatten(item):
- yield flat
diff --git a/src/python/m5/smartdict.py b/src/python/m5/util/smartdict.py
index d85dbd517..d85dbd517 100644
--- a/src/python/m5/smartdict.py
+++ b/src/python/m5/util/smartdict.py
diff --git a/src/sim/System.py b/src/sim/System.py
index 3b0bc1e46..06a54a78d 100644
--- a/src/sim/System.py
+++ b/src/sim/System.py
@@ -27,9 +27,10 @@
# Authors: Nathan Binkert
from m5.SimObject import SimObject
+from m5.defines import buildEnv
from m5.params import *
from m5.proxy import *
-from m5 import build_env
+
from PhysicalMemory import *
class MemoryMode(Enum): vals = ['invalid', 'atomic', 'timing']
@@ -40,7 +41,7 @@ class System(SimObject):
physmem = Param.PhysicalMemory(Parent.any, "physical memory")
mem_mode = Param.MemoryMode('atomic', "The mode the memory system is in")
- if build_env['FULL_SYSTEM']:
+ if buildEnv['FULL_SYSTEM']:
abstract = True
boot_cpu_frequency = Param.Frequency(Self.cpu[0].clock.frequency,
"boot processor frequency")
diff --git a/src/sim/arguments.cc b/src/sim/arguments.cc
index 5aa57755a..339a57f90 100644
--- a/src/sim/arguments.cc
+++ b/src/sim/arguments.cc
@@ -28,11 +28,10 @@
* Authors: Nathan Binkert
*/
-#include "sim/arguments.hh"
#include "arch/utility.hh"
+#include "config/the_isa.hh"
#include "cpu/thread_context.hh"
-
-using namespace TheISA;
+#include "sim/arguments.hh"
Arguments::Data::~Data()
{
diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh
index 29efdeb6f..92c38142c 100644
--- a/src/sim/eventq.hh
+++ b/src/sim/eventq.hh
@@ -471,7 +471,7 @@ class EventWrapper : public Event
inline void
EventQueue::schedule(Event *event, Tick when)
{
- assert(when >= curTick);
+ assert((UTick)when >= (UTick)curTick);
assert(!event->scheduled());
#ifdef EVENTQ_DEBUG
assert((event->flags & Event::Initialized) == Event::Initialized);
diff --git a/src/sim/process.cc b/src/sim/process.cc
index 55bd2f209..343d2ad5a 100644
--- a/src/sim/process.cc
+++ b/src/sim/process.cc
@@ -32,6 +32,8 @@
#include <unistd.h>
#include <fcntl.h>
+
+#include <cstdio>
#include <string>
#include "arch/remote_gdb.hh"
@@ -40,6 +42,7 @@
#include "base/loader/symtab.hh"
#include "base/statistics.hh"
#include "config/full_system.hh"
+#include "config/the_isa.hh"
#include "cpu/thread_context.hh"
#include "mem/page_table.hh"
#include "mem/physical.hh"
@@ -53,7 +56,6 @@
#include "sim/syscall_emul.hh"
#include "sim/system.hh"
-#include "arch/isa_specific.hh"
#if THE_ISA == ALPHA_ISA
#include "arch/alpha/linux/process.hh"
#include "arch/alpha/tru64/process.hh"
@@ -66,6 +68,8 @@
#include "arch/arm/linux/process.hh"
#elif THE_ISA == X86_ISA
#include "arch/x86/linux/process.hh"
+#elif THE_ISA == POWER_ISA
+#include "arch/power/linux/process.hh"
#else
#error "THE_ISA not set"
#endif
@@ -626,7 +630,7 @@ LiveProcess::argsInit(int intSize, int pageSize)
tc->setPC(prog_entry);
tc->setNextPC(prog_entry + sizeof(MachInst));
-#if THE_ISA != ALPHA_ISA //e.g. MIPS or Sparc
+#if THE_ISA != ALPHA_ISA && THE_ISA != POWER_ISA //e.g. MIPS or Sparc
tc->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
#endif
@@ -645,6 +649,12 @@ LiveProcess::syscall(int64_t callnum, ThreadContext *tc)
desc->doSyscall(callnum, this, tc);
}
+IntReg
+LiveProcess::getSyscallArg(ThreadContext *tc, int &i, int width)
+{
+ return getSyscallArg(tc, i);
+}
+
LiveProcess *
LiveProcess::create(LiveProcessParams * params)
{
@@ -754,6 +764,20 @@ LiveProcess::create(LiveProcessParams * params)
default:
fatal("Unknown/unsupported operating system.");
}
+#elif THE_ISA == POWER_ISA
+ if (objFile->getArch() != ObjectFile::Power)
+ fatal("Object file architecture does not match compiled ISA (Power).");
+ switch (objFile->getOpSys()) {
+ case ObjectFile::UnknownOpSys:
+ warn("Unknown operating system; assuming Linux.");
+ // fall through
+ case ObjectFile::Linux:
+ process = new PowerLinuxProcess(params, objFile);
+ break;
+
+ default:
+ fatal("Unknown/unsupported operating system.");
+ }
#else
#error "THE_ISA not set"
#endif
diff --git a/src/sim/process.hh b/src/sim/process.hh
index 05a48071a..ab9d64cf3 100644
--- a/src/sim/process.hh
+++ b/src/sim/process.hh
@@ -47,9 +47,11 @@
#include "arch/registers.hh"
#include "base/statistics.hh"
#include "base/types.hh"
+#include "config/the_isa.hh"
#include "sim/sim_object.hh"
#include "sim/syscallreturn.hh"
+class BaseRemoteGDB;
class GDBListener;
class PageTable;
class ProcessParams;
@@ -58,10 +60,6 @@ class SyscallDesc;
class System;
class ThreadContext;
class TranslatingPort;
-namespace TheISA
-{
- class RemoteGDB;
-}
template<class IntType>
struct AuxVector
@@ -94,7 +92,7 @@ class Process : public SimObject
std::vector<int> contextIds;
// remote gdb objects
- std::vector<TheISA::RemoteGDB *> remoteGDB;
+ std::vector<BaseRemoteGDB *> remoteGDB;
std::vector<GDBListener *> gdbListen;
bool breakpoint();
@@ -327,7 +325,9 @@ class LiveProcess : public Process
std::string getcwd() const { return cwd; }
virtual void syscall(int64_t callnum, ThreadContext *tc);
- virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int i) = 0;
+
+ virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int &i) = 0;
+ virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int &i, int width);
virtual void setSyscallArg(ThreadContext *tc,
int i, TheISA::IntReg val) = 0;
virtual void setSyscallReturn(ThreadContext *tc,
diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc
index 6182150d4..cf063818b 100644
--- a/src/sim/pseudo_inst.cc
+++ b/src/sim/pseudo_inst.cc
@@ -35,10 +35,10 @@
#include <fstream>
#include <string>
-#include "config/full_system.hh"
-
#include "arch/vtophys.hh"
#include "base/debug.hh"
+#include "config/full_system.hh"
+#include "config/the_isa.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "cpu/quiesce_event.hh"
diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc
index 811bdb73a..4726decc5 100644
--- a/src/sim/syscall_emul.cc
+++ b/src/sim/syscall_emul.cc
@@ -32,18 +32,19 @@
#include <fcntl.h>
#include <unistd.h>
-#include <string>
+#include <cstdio>
#include <iostream>
+#include <string>
#include "sim/syscall_emul.hh"
#include "base/chunk_generator.hh"
#include "base/trace.hh"
+#include "config/the_isa.hh"
#include "cpu/thread_context.hh"
#include "cpu/base.hh"
#include "mem/page_table.hh"
#include "sim/process.hh"
#include "sim/system.hh"
-
#include "sim/sim_exit.hh"
using namespace std;
@@ -52,11 +53,16 @@ using namespace TheISA;
void
SyscallDesc::doSyscall(int callnum, LiveProcess *process, ThreadContext *tc)
{
+#if TRACING_ON
+ int index = 0;
+#endif
DPRINTFR(SyscallVerbose,
"%d: %s: syscall %s called w/arguments %d,%d,%d,%d\n",
curTick, tc->getCpuPtr()->name(), name,
- process->getSyscallArg(tc, 0), process->getSyscallArg(tc, 1),
- process->getSyscallArg(tc, 2), process->getSyscallArg(tc, 3));
+ process->getSyscallArg(tc, index),
+ process->getSyscallArg(tc, index),
+ process->getSyscallArg(tc, index),
+ process->getSyscallArg(tc, index));
SyscallReturn retval = (*funcPtr)(this, callnum, process, tc);
@@ -82,8 +88,9 @@ SyscallReturn
ignoreFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
+ int index = 0;
warn("ignoring syscall %s(%d, %d, ...)", desc->name,
- process->getSyscallArg(tc, 0), process->getSyscallArg(tc, 1));
+ process->getSyscallArg(tc, index), process->getSyscallArg(tc, index));
return 0;
}
@@ -95,8 +102,9 @@ exitFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
{
if (process->system->numRunningContexts() == 1) {
// Last running context... exit simulator
+ int index = 0;
exitSimLoop("target called exit()",
- process->getSyscallArg(tc, 0) & 0xff);
+ process->getSyscallArg(tc, index) & 0xff);
} else {
// other running threads... just halt this one
tc->halt();
@@ -112,8 +120,9 @@ exitGroupFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
{
// really should just halt all thread contexts belonging to this
// process in case there's another process running...
+ int index = 0;
exitSimLoop("target called exit()",
- process->getSyscallArg(tc, 0) & 0xff);
+ process->getSyscallArg(tc, index) & 0xff);
return 1;
}
@@ -130,7 +139,8 @@ SyscallReturn
brkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
{
// change brk addr to first arg
- Addr new_brk = p->getSyscallArg(tc, 0);
+ int index = 0;
+ Addr new_brk = p->getSyscallArg(tc, index);
// in Linux at least, brk(0) returns the current break value
// (note that the syscall and the glibc function have different behavior)
@@ -144,6 +154,24 @@ brkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
if (!p->pTable->translate(gen.addr()))
p->pTable->allocate(roundDown(gen.addr(), VMPageSize),
VMPageSize);
+
+ // if the address is already there, zero it out
+ else {
+ uint8_t zero = 0;
+ TranslatingPort *tp = tc->getMemPort();
+
+ // split non-page aligned accesses
+ Addr next_page = roundUp(gen.addr(), VMPageSize);
+ uint32_t size_needed = next_page - gen.addr();
+ tp->memsetBlob(gen.addr(), zero, size_needed);
+ if (gen.addr() + VMPageSize > next_page &&
+ next_page < new_brk &&
+ p->pTable->translate(next_page))
+ {
+ size_needed = VMPageSize - size_needed;
+ tp->memsetBlob(next_page, zero, size_needed);
+ }
+ }
}
}
@@ -156,7 +184,8 @@ brkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
SyscallReturn
closeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
{
- int target_fd = p->getSyscallArg(tc, 0);
+ int index = 0;
+ int target_fd = p->getSyscallArg(tc, index);
int status = close(p->sim_fd(target_fd));
if (status >= 0)
p->free_fd(target_fd);
@@ -167,9 +196,11 @@ closeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
SyscallReturn
readFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
{
- int fd = p->sim_fd(p->getSyscallArg(tc, 0));
- int nbytes = p->getSyscallArg(tc, 2);
- BufferArg bufArg(p->getSyscallArg(tc, 1), nbytes);
+ int index = 0;
+ int fd = p->sim_fd(p->getSyscallArg(tc, index));
+ Addr bufPtr = p->getSyscallArg(tc, index);
+ int nbytes = p->getSyscallArg(tc, index);
+ BufferArg bufArg(bufPtr, nbytes);
int bytes_read = read(fd, bufArg.bufferPtr(), nbytes);
@@ -182,9 +213,11 @@ readFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
SyscallReturn
writeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
{
- int fd = p->sim_fd(p->getSyscallArg(tc, 0));
- int nbytes = p->getSyscallArg(tc, 2);
- BufferArg bufArg(p->getSyscallArg(tc, 1), nbytes);
+ int index = 0;
+ int fd = p->sim_fd(p->getSyscallArg(tc, index));
+ Addr bufPtr = p->getSyscallArg(tc, index);
+ int nbytes = p->getSyscallArg(tc, index);
+ BufferArg bufArg(bufPtr, nbytes);
bufArg.copyIn(tc->getMemPort());
@@ -199,9 +232,10 @@ writeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
SyscallReturn
lseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
{
- int fd = p->sim_fd(p->getSyscallArg(tc, 0));
- uint64_t offs = p->getSyscallArg(tc, 1);
- int whence = p->getSyscallArg(tc, 2);
+ int index = 0;
+ int fd = p->sim_fd(p->getSyscallArg(tc, index));
+ uint64_t offs = p->getSyscallArg(tc, index);
+ int whence = p->getSyscallArg(tc, index);
off_t result = lseek(fd, offs, whence);
@@ -212,11 +246,12 @@ lseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
SyscallReturn
_llseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
{
- int fd = p->sim_fd(p->getSyscallArg(tc, 0));
- uint64_t offset_high = p->getSyscallArg(tc, 1);
- uint32_t offset_low = p->getSyscallArg(tc, 2);
- Addr result_ptr = p->getSyscallArg(tc, 3);
- int whence = p->getSyscallArg(tc, 4);
+ int index = 0;
+ int fd = p->sim_fd(p->getSyscallArg(tc, index));
+ uint64_t offset_high = p->getSyscallArg(tc, index);
+ uint32_t offset_low = p->getSyscallArg(tc, index);
+ Addr result_ptr = p->getSyscallArg(tc, index);
+ int whence = p->getSyscallArg(tc, index);
uint64_t offset = (offset_high << 32) | offset_low;
@@ -255,8 +290,10 @@ const char *hostname = "m5.eecs.umich.edu";
SyscallReturn
gethostnameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
{
- int name_len = p->getSyscallArg(tc, 1);
- BufferArg name(p->getSyscallArg(tc, 0), name_len);
+ int index = 0;
+ Addr bufPtr = p->getSyscallArg(tc, index);
+ int name_len = p->getSyscallArg(tc, index);
+ BufferArg name(bufPtr, name_len);
strncpy((char *)name.bufferPtr(), hostname, name_len);
@@ -269,8 +306,10 @@ SyscallReturn
getcwdFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
{
int result = 0;
- unsigned long size = p->getSyscallArg(tc, 1);
- BufferArg buf(p->getSyscallArg(tc, 0), size);
+ int index = 0;
+ Addr bufPtr = p->getSyscallArg(tc, index);
+ unsigned long size = p->getSyscallArg(tc, index);
+ BufferArg buf(bufPtr, size);
// Is current working directory defined?
string cwd = p->getcwd();
@@ -302,14 +341,17 @@ readlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
{
string path;
- if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0)))
+ int index = 0;
+ if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index)))
return (TheISA::IntReg)-EFAULT;
// Adjust path for current working directory
path = p->fullPath(path);
- size_t bufsiz = p->getSyscallArg(tc, 2);
- BufferArg buf(p->getSyscallArg(tc, 1), bufsiz);
+ Addr bufPtr = p->getSyscallArg(tc, index);
+ size_t bufsiz = p->getSyscallArg(tc, index);
+
+ BufferArg buf(bufPtr, bufsiz);
int result = readlink(path.c_str(), (char *)buf.bufferPtr(), bufsiz);
@@ -323,7 +365,8 @@ unlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
{
string path;
- if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0)))
+ int index = 0;
+ if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index)))
return (TheISA::IntReg)-EFAULT;
// Adjust path for current working directory
@@ -339,13 +382,14 @@ mkdirFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
{
string path;
- if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0)))
+ int index = 0;
+ if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index)))
return (TheISA::IntReg)-EFAULT;
// Adjust path for current working directory
path = p->fullPath(path);
- mode_t mode = p->getSyscallArg(tc, 1);
+ mode_t mode = p->getSyscallArg(tc, index);
int result = mkdir(path.c_str(), mode);
return (result == -1) ? -errno : result;
@@ -356,12 +400,13 @@ renameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
{
string old_name;
- if (!tc->getMemPort()->tryReadString(old_name, p->getSyscallArg(tc, 0)))
+ int index = 0;
+ if (!tc->getMemPort()->tryReadString(old_name, p->getSyscallArg(tc, index)))
return -EFAULT;
string new_name;
- if (!tc->getMemPort()->tryReadString(new_name, p->getSyscallArg(tc, 1)))
+ if (!tc->getMemPort()->tryReadString(new_name, p->getSyscallArg(tc, index)))
return -EFAULT;
// Adjust path for current working directory
@@ -377,10 +422,11 @@ truncateFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
{
string path;
- if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0)))
+ int index = 0;
+ if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index)))
return -EFAULT;
- off_t length = p->getSyscallArg(tc, 1);
+ off_t length = p->getSyscallArg(tc, index);
// Adjust path for current working directory
path = p->fullPath(path);
@@ -393,18 +439,62 @@ SyscallReturn
ftruncateFunc(SyscallDesc *desc, int num,
LiveProcess *process, ThreadContext *tc)
{
- int fd = process->sim_fd(process->getSyscallArg(tc, 0));
+ int index = 0;
+ int fd = process->sim_fd(process->getSyscallArg(tc, index));
if (fd < 0)
return -EBADF;
- off_t length = process->getSyscallArg(tc, 1);
+ off_t length = process->getSyscallArg(tc, index);
int result = ftruncate(fd, length);
return (result == -1) ? -errno : result;
}
SyscallReturn
+truncate64Func(SyscallDesc *desc, int num,
+ LiveProcess *process, ThreadContext *tc)
+{
+ int index = 0;
+ string path;
+
+ if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, index)))
+ return -EFAULT;
+
+ int64_t length = process->getSyscallArg(tc, index, 64);
+
+ // Adjust path for current working directory
+ path = process->fullPath(path);
+
+#if NO_STAT64
+ int result = truncate(path.c_str(), length);
+#else
+ int result = truncate64(path.c_str(), length);
+#endif
+ return (result == -1) ? -errno : result;
+}
+
+SyscallReturn
+ftruncate64Func(SyscallDesc *desc, int num,
+ LiveProcess *process, ThreadContext *tc)
+{
+ int index = 0;
+ int fd = process->sim_fd(process->getSyscallArg(tc, index));
+
+ if (fd < 0)
+ return -EBADF;
+
+ int64_t length = process->getSyscallArg(tc, index, 64);
+
+#if NO_STAT64
+ int result = ftruncate(fd, length);
+#else
+ int result = ftruncate64(fd, length);
+#endif
+ return (result == -1) ? -errno : result;
+}
+
+SyscallReturn
umaskFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc)
{
// Letting the simulated program change the simulator's umask seems like
@@ -420,13 +510,14 @@ chownFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
{
string path;
- if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, 0)))
+ int index = 0;
+ if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index)))
return -EFAULT;
/* XXX endianess */
- uint32_t owner = p->getSyscallArg(tc, 1);
+ uint32_t owner = p->getSyscallArg(tc, index);
uid_t hostOwner = owner;
- uint32_t group = p->getSyscallArg(tc, 2);
+ uint32_t group = p->getSyscallArg(tc, index);
gid_t hostGroup = group;
// Adjust path for current working directory
@@ -439,15 +530,16 @@ chownFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
SyscallReturn
fchownFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc)
{
- int fd = process->sim_fd(process->getSyscallArg(tc, 0));
+ int index = 0;
+ int fd = process->sim_fd(process->getSyscallArg(tc, index));
if (fd < 0)
return -EBADF;
/* XXX endianess */
- uint32_t owner = process->getSyscallArg(tc, 1);
+ uint32_t owner = process->getSyscallArg(tc, index);
uid_t hostOwner = owner;
- uint32_t group = process->getSyscallArg(tc, 2);
+ uint32_t group = process->getSyscallArg(tc, index);
gid_t hostGroup = group;
int result = fchown(fd, hostOwner, hostGroup);
@@ -458,11 +550,12 @@ fchownFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc)
SyscallReturn
dupFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc)
{
- int fd = process->sim_fd(process->getSyscallArg(tc, 0));
+ int index = 0;
+ int fd = process->sim_fd(process->getSyscallArg(tc, index));
if (fd < 0)
return -EBADF;
- Process::FdMap *fdo = process->sim_fd_obj(process->getSyscallArg(tc, 0));
+ Process::FdMap *fdo = process->sim_fd_obj(fd);
int result = dup(fd);
return (result == -1) ? -errno :
@@ -474,12 +567,13 @@ SyscallReturn
fcntlFunc(SyscallDesc *desc, int num, LiveProcess *process,
ThreadContext *tc)
{
- int fd = process->getSyscallArg(tc, 0);
+ int index = 0;
+ int fd = process->getSyscallArg(tc, index);
if (fd < 0 || process->sim_fd(fd) < 0)
return -EBADF;
- int cmd = process->getSyscallArg(tc, 1);
+ int cmd = process->getSyscallArg(tc, index);
switch (cmd) {
case 0: // F_DUPFD
// if we really wanted to support this, we'd need to do it
@@ -516,12 +610,13 @@ SyscallReturn
fcntl64Func(SyscallDesc *desc, int num, LiveProcess *process,
ThreadContext *tc)
{
- int fd = process->getSyscallArg(tc, 0);
+ int index = 0;
+ int fd = process->getSyscallArg(tc, index);
if (fd < 0 || process->sim_fd(fd) < 0)
return -EBADF;
- int cmd = process->getSyscallArg(tc, 1);
+ int cmd = process->getSyscallArg(tc, index);
switch (cmd) {
case 33: //F_GETLK64
warn("fcntl64(%d, F_GETLK64) not supported, error returned\n", fd);
@@ -605,7 +700,8 @@ setuidFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
// can't fathom why a benchmark would call this.
- warn("Ignoring call to setuid(%d)\n", process->getSyscallArg(tc, 0));
+ int index = 0;
+ warn("Ignoring call to setuid(%d)\n", process->getSyscallArg(tc, index));
return 0;
}
@@ -661,17 +757,20 @@ SyscallReturn
cloneFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
+ int index = 0;
+ IntReg flags = process->getSyscallArg(tc, index);
+ IntReg newStack = process->getSyscallArg(tc, index);
+
DPRINTF(SyscallVerbose, "In sys_clone:\n");
- DPRINTF(SyscallVerbose, " Flags=%llx\n", process->getSyscallArg(tc, 0));
- DPRINTF(SyscallVerbose, " Child stack=%llx\n",
- process->getSyscallArg(tc, 1));
+ DPRINTF(SyscallVerbose, " Flags=%llx\n", flags);
+ DPRINTF(SyscallVerbose, " Child stack=%llx\n", newStack);
- if (process->getSyscallArg(tc, 0) != 0x10f00) {
+ if (flags != 0x10f00) {
warn("This sys_clone implementation assumes flags "
"CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD "
"(0x10f00), and may not work correctly with given flags "
- "0x%llx\n", process->getSyscallArg(tc, 0));
+ "0x%llx\n", flags);
}
ThreadContext* ctc; // child thread context
@@ -704,7 +803,7 @@ cloneFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
#endif
// Set up stack register
- ctc->setIntReg(TheISA::StackPointerReg, process->getSyscallArg(tc, 1));
+ ctc->setIntReg(TheISA::StackPointerReg, newStack);
// Set up syscall return values in parent and child
ctc->setIntReg(ReturnValueReg, 0); // return value, child
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index 5f2ebd428..66e800183 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -55,10 +55,12 @@
#include "base/misc.hh"
#include "base/trace.hh"
#include "base/types.hh"
+#include "config/the_isa.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "mem/translating_port.hh"
#include "mem/page_table.hh"
+#include "sim/system.hh"
#include "sim/process.hh"
///
@@ -258,6 +260,15 @@ SyscallReturn ftruncateFunc(SyscallDesc *desc, int num,
LiveProcess *p, ThreadContext *tc);
+/// Target truncate64() handler.
+SyscallReturn truncate64Func(SyscallDesc *desc, int num,
+ LiveProcess *p, ThreadContext *tc);
+
+/// Target ftruncate64() handler.
+SyscallReturn ftruncate64Func(SyscallDesc *desc, int num,
+ LiveProcess *p, ThreadContext *tc);
+
+
/// Target umask() handler.
SyscallReturn umaskFunc(SyscallDesc *desc, int num,
LiveProcess *p, ThreadContext *tc);
@@ -462,7 +473,7 @@ copyOutStat64Buf(TranslatingPort * mem, Addr addr,
{
typedef TypedBufferArg<typename OS::tgt_stat64> tgt_stat_buf;
tgt_stat_buf tgt(addr);
- convertStatBuf<tgt_stat_buf, hst_stat64>(tgt, host, fakeTTY);
+ convertStat64Buf<tgt_stat_buf, hst_stat64>(tgt, host, fakeTTY);
tgt.copyOut(mem);
}
@@ -474,8 +485,9 @@ SyscallReturn
ioctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- int fd = process->getSyscallArg(tc, 0);
- unsigned req = process->getSyscallArg(tc, 1);
+ int index = 0;
+ int fd = process->getSyscallArg(tc, index);
+ unsigned req = process->getSyscallArg(tc, index);
DPRINTF(SyscallVerbose, "ioctl(%d, 0x%x, ...)\n", fd, req);
@@ -493,6 +505,7 @@ ioctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
case OS::TIOCGETC_:
case OS::TIOCGETS_:
case OS::TIOCGETA_:
+ case OS::TCSETAW_:
return -ENOTTY;
default:
@@ -509,7 +522,9 @@ openFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
{
std::string path;
- if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
+ int index = 0;
+ if (!tc->getMemPort()->tryReadString(path,
+ process->getSyscallArg(tc, index)))
return -EFAULT;
if (path == "/dev/sysdev0") {
@@ -519,8 +534,8 @@ openFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
return -ENOENT;
}
- int tgtFlags = process->getSyscallArg(tc, 1);
- int mode = process->getSyscallArg(tc, 2);
+ int tgtFlags = process->getSyscallArg(tc, index);
+ int mode = process->getSyscallArg(tc, index);
int hostFlags = 0;
// translate open flags
@@ -558,6 +573,24 @@ openFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
}
+/// Target sysinfo() handler.
+template <class OS>
+SyscallReturn
+sysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+ ThreadContext *tc)
+{
+
+ int index = 0;
+ TypedBufferArg<typename OS::tgt_sysinfo>
+ sysinfo(process->getSyscallArg(tc, index));
+
+ sysinfo->uptime=seconds_since_epoch;
+ sysinfo->totalram=process->system->memSize();
+
+ sysinfo.copyOut(tc->getMemPort());
+
+ return 0;
+}
/// Target chmod() handler.
template <class OS>
@@ -567,10 +600,13 @@ chmodFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
{
std::string path;
- if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
+ int index = 0;
+ if (!tc->getMemPort()->tryReadString(path,
+ process->getSyscallArg(tc, index))) {
return -EFAULT;
+ }
- uint32_t mode = process->getSyscallArg(tc, 1);
+ uint32_t mode = process->getSyscallArg(tc, index);
mode_t hostMode = 0;
// XXX translate mode flags via OS::something???
@@ -594,13 +630,14 @@ SyscallReturn
fchmodFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- int fd = process->getSyscallArg(tc, 0);
+ int index = 0;
+ int fd = process->getSyscallArg(tc, index);
if (fd < 0 || process->sim_fd(fd) < 0) {
// doesn't map to any simulator fd: not a valid target fd
return -EBADF;
}
- uint32_t mode = process->getSyscallArg(tc, 1);
+ uint32_t mode = process->getSyscallArg(tc, index);
mode_t hostMode = 0;
// XXX translate mode flags via OS::someting???
@@ -619,10 +656,11 @@ template <class OS>
SyscallReturn
mremapFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc)
{
- Addr start = process->getSyscallArg(tc, 0);
- uint64_t old_length = process->getSyscallArg(tc, 1);
- uint64_t new_length = process->getSyscallArg(tc, 2);
- uint64_t flags = process->getSyscallArg(tc, 3);
+ int index = 0;
+ Addr start = process->getSyscallArg(tc, index);
+ uint64_t old_length = process->getSyscallArg(tc, index);
+ uint64_t new_length = process->getSyscallArg(tc, index);
+ uint64_t flags = process->getSyscallArg(tc, index);
if ((start % TheISA::VMPageSize != 0) ||
(new_length % TheISA::VMPageSize != 0)) {
@@ -668,8 +706,12 @@ statFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
{
std::string path;
- if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
- return -EFAULT;
+ int index = 0;
+ if (!tc->getMemPort()->tryReadString(path,
+ process->getSyscallArg(tc, index))) {
+ return -EFAULT;
+ }
+ Addr bufPtr = process->getSyscallArg(tc, index);
// Adjust path for current working directory
path = process->fullPath(path);
@@ -680,8 +722,7 @@ statFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
if (result < 0)
return -errno;
- copyOutStatBuf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1),
- &hostBuf);
+ copyOutStatBuf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
return 0;
}
@@ -695,8 +736,11 @@ stat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
{
std::string path;
- if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
+ int index = 0;
+ if (!tc->getMemPort()->tryReadString(path,
+ process->getSyscallArg(tc, index)))
return -EFAULT;
+ Addr bufPtr = process->getSyscallArg(tc, index);
// Adjust path for current working directory
path = process->fullPath(path);
@@ -712,8 +756,7 @@ stat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
if (result < 0)
return -errno;
- copyOutStat64Buf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1),
- &hostBuf);
+ copyOutStat64Buf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
return 0;
}
@@ -725,7 +768,9 @@ SyscallReturn
fstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- int fd = process->getSyscallArg(tc, 0);
+ int index = 0;
+ int fd = process->getSyscallArg(tc, index);
+ Addr bufPtr = process->getSyscallArg(tc, index);
if (fd < 0 || process->sim_fd(fd) < 0) {
// doesn't map to any simulator fd: not a valid target fd
return -EBADF;
@@ -742,8 +787,7 @@ fstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
if (result < 0)
return -errno;
- copyOutStat64Buf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1),
- &hostBuf, (fd == 1));
+ copyOutStat64Buf<OS>(tc->getMemPort(), bufPtr, &hostBuf, (fd == 1));
return 0;
}
@@ -757,8 +801,12 @@ lstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
{
std::string path;
- if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
- return -EFAULT;
+ int index = 0;
+ if (!tc->getMemPort()->tryReadString(path,
+ process->getSyscallArg(tc, index))) {
+ return -EFAULT;
+ }
+ Addr bufPtr = process->getSyscallArg(tc, index);
// Adjust path for current working directory
path = process->fullPath(path);
@@ -769,8 +817,7 @@ lstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
if (result < 0)
return -errno;
- copyOutStatBuf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1),
- &hostBuf);
+ copyOutStatBuf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
return 0;
}
@@ -783,8 +830,12 @@ lstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
{
std::string path;
- if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
- return -EFAULT;
+ int index = 0;
+ if (!tc->getMemPort()->tryReadString(path,
+ process->getSyscallArg(tc, index))) {
+ return -EFAULT;
+ }
+ Addr bufPtr = process->getSyscallArg(tc, index);
// Adjust path for current working directory
path = process->fullPath(path);
@@ -800,8 +851,7 @@ lstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
if (result < 0)
return -errno;
- copyOutStat64Buf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1),
- &hostBuf);
+ copyOutStat64Buf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
return 0;
}
@@ -812,7 +862,9 @@ SyscallReturn
fstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- int fd = process->sim_fd(process->getSyscallArg(tc, 0));
+ int index = 0;
+ int fd = process->sim_fd(process->getSyscallArg(tc, index));
+ Addr bufPtr = process->getSyscallArg(tc, index);
DPRINTF(SyscallVerbose, "fstat(%d, ...)\n", fd);
@@ -825,8 +877,7 @@ fstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
if (result < 0)
return -errno;
- copyOutStatBuf<OS>(tc->getMemPort(), process->getSyscallArg(tc, 1),
- &hostBuf, (fd == 1));
+ copyOutStatBuf<OS>(tc->getMemPort(), bufPtr, &hostBuf, (fd == 1));
return 0;
}
@@ -840,8 +891,12 @@ statfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
{
std::string path;
- if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
- return -EFAULT;
+ int index = 0;
+ if (!tc->getMemPort()->tryReadString(path,
+ process->getSyscallArg(tc, index))) {
+ return -EFAULT;
+ }
+ Addr bufPtr = process->getSyscallArg(tc, index);
// Adjust path for current working directory
path = process->fullPath(path);
@@ -852,8 +907,7 @@ statfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
if (result < 0)
return -errno;
- OS::copyOutStatfsBuf(tc->getMemPort(),
- (Addr)(process->getSyscallArg(tc, 1)), &hostBuf);
+ OS::copyOutStatfsBuf(tc->getMemPort(), bufPtr, &hostBuf);
return 0;
}
@@ -865,7 +919,9 @@ SyscallReturn
fstatfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- int fd = process->sim_fd(process->getSyscallArg(tc, 0));
+ int index = 0;
+ int fd = process->sim_fd(process->getSyscallArg(tc, index));
+ Addr bufPtr = process->getSyscallArg(tc, index);
if (fd < 0)
return -EBADF;
@@ -876,8 +932,7 @@ fstatfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
if (result < 0)
return -errno;
- OS::copyOutStatfsBuf(tc->getMemPort(), process->getSyscallArg(tc, 1),
- &hostBuf);
+ OS::copyOutStatfsBuf(tc->getMemPort(), bufPtr, &hostBuf);
return 0;
}
@@ -889,15 +944,16 @@ SyscallReturn
writevFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- int fd = process->getSyscallArg(tc, 0);
+ int index = 0;
+ int fd = process->getSyscallArg(tc, index);
if (fd < 0 || process->sim_fd(fd) < 0) {
// doesn't map to any simulator fd: not a valid target fd
return -EBADF;
}
TranslatingPort *p = tc->getMemPort();
- uint64_t tiov_base = process->getSyscallArg(tc, 1);
- size_t count = process->getSyscallArg(tc, 2);
+ uint64_t tiov_base = process->getSyscallArg(tc, index);
+ size_t count = process->getSyscallArg(tc, index);
struct iovec hiov[count];
for (size_t i = 0; i < count; ++i) {
typename OS::tgt_iovec tiov;
@@ -938,12 +994,13 @@ template <class OS>
SyscallReturn
mmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
{
- Addr start = p->getSyscallArg(tc, 0);
- uint64_t length = p->getSyscallArg(tc, 1);
- // int prot = p->getSyscallArg(tc, 2);
- int flags = p->getSyscallArg(tc, 3);
- // int fd = p->sim_fd(p->getSyscallArg(tc, 4));
- // int offset = p->getSyscallArg(tc, 5);
+ int index = 0;
+ Addr start = p->getSyscallArg(tc, index);
+ uint64_t length = p->getSyscallArg(tc, index);
+ index++; // int prot = p->getSyscallArg(tc, index);
+ int flags = p->getSyscallArg(tc, index);
+ int fd = p->sim_fd(p->getSyscallArg(tc, index));
+ // int offset = p->getSyscallArg(tc, index);
if ((start % TheISA::VMPageSize) != 0 ||
@@ -960,13 +1017,18 @@ mmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
}
// pick next address from our "mmap region"
- start = p->mmap_end;
+ if (OS::mmapGrowsDown()) {
+ start = p->mmap_end - length;
+ p->mmap_end = start;
+ } else {
+ start = p->mmap_end;
+ p->mmap_end += length;
+ }
p->pTable->allocate(start, length);
- p->mmap_end += length;
if (!(flags & OS::TGT_MAP_ANONYMOUS)) {
warn("allowing mmap of file @ fd %d. "
- "This will break if not /dev/zero.", p->getSyscallArg(tc, 4));
+ "This will break if not /dev/zero.", fd);
}
return start;
@@ -978,8 +1040,9 @@ SyscallReturn
getrlimitFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- unsigned resource = process->getSyscallArg(tc, 0);
- TypedBufferArg<typename OS::rlimit> rlp(process->getSyscallArg(tc, 1));
+ int index = 0;
+ unsigned resource = process->getSyscallArg(tc, index);
+ TypedBufferArg<typename OS::rlimit> rlp(process->getSyscallArg(tc, index));
switch (resource) {
case OS::TGT_RLIMIT_STACK:
@@ -1013,7 +1076,8 @@ SyscallReturn
gettimeofdayFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- TypedBufferArg<typename OS::timeval> tp(process->getSyscallArg(tc, 0));
+ int index = 0;
+ TypedBufferArg<typename OS::timeval> tp(process->getSyscallArg(tc, index));
getElapsedTime(tp->tv_sec, tp->tv_usec);
tp->tv_sec += seconds_since_epoch;
@@ -1034,10 +1098,14 @@ utimesFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
{
std::string path;
- if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, 0)))
- return -EFAULT;
+ int index = 0;
+ if (!tc->getMemPort()->tryReadString(path,
+ process->getSyscallArg(tc, index))) {
+ return -EFAULT;
+ }
- TypedBufferArg<typename OS::timeval [2]> tp(process->getSyscallArg(tc, 1));
+ TypedBufferArg<typename OS::timeval [2]>
+ tp(process->getSyscallArg(tc, index));
tp.copyIn(tc->getMemPort());
struct timeval hostTimeval[2];
@@ -1063,8 +1131,9 @@ SyscallReturn
getrusageFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
- int who = process->getSyscallArg(tc, 0); // THREAD, SELF, or CHILDREN
- TypedBufferArg<typename OS::rusage> rup(process->getSyscallArg(tc, 1));
+ int index = 0;
+ int who = process->getSyscallArg(tc, index); // THREAD, SELF, or CHILDREN
+ TypedBufferArg<typename OS::rusage> rup(process->getSyscallArg(tc, index));
rup->ru_utime.tv_sec = 0;
rup->ru_utime.tv_usec = 0;
@@ -1108,7 +1177,52 @@ getrusageFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
return 0;
}
+/// Target times() function.
+template <class OS>
+SyscallReturn
+timesFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+ ThreadContext *tc)
+{
+ int index = 0;
+ TypedBufferArg<typename OS::tms> bufp(process->getSyscallArg(tc, index));
+
+ // Fill in the time structure (in clocks)
+ int64_t clocks = curTick * OS::M5_SC_CLK_TCK / Clock::Int::s;
+ bufp->tms_utime = clocks;
+ bufp->tms_stime = 0;
+ bufp->tms_cutime = 0;
+ bufp->tms_cstime = 0;
+ // Convert to host endianness
+ bufp->tms_utime = htog(bufp->tms_utime);
+
+ // Write back
+ bufp.copyOut(tc->getMemPort());
+
+ // Return clock ticks since system boot
+ return clocks;
+}
+
+/// Target time() function.
+template <class OS>
+SyscallReturn
+timeFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+ ThreadContext *tc)
+{
+ typename OS::time_t sec, usec;
+ getElapsedTime(sec, usec);
+ sec += seconds_since_epoch;
+
+ int index = 0;
+ Addr taddr = (Addr)process->getSyscallArg(tc, index);
+ if(taddr != 0) {
+ typename OS::time_t t = sec;
+ t = htog(t);
+ TranslatingPort *p = tc->getMemPort();
+ p->writeBlob(taddr, (uint8_t*)&t, (int)sizeof(typename OS::time_t));
+ }
+ return sec;
+}
#endif // __SIM_SYSCALL_EMUL_HH__
diff --git a/src/sim/system.cc b/src/sim/system.cc
index f10167bba..da77f1995 100644
--- a/src/sim/system.cc
+++ b/src/sim/system.cc
@@ -38,11 +38,14 @@
#include "base/loader/symtab.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
+#include "config/full_system.hh"
+#include "config/the_isa.hh"
#include "mem/mem_object.hh"
#include "mem/physical.hh"
#include "sim/byteswap.hh"
#include "sim/system.hh"
#include "sim/debug.hh"
+
#if FULL_SYSTEM
#include "arch/vtophys.hh"
#include "kern/kernel_stats.hh"
diff --git a/src/sim/system.hh b/src/sim/system.hh
index aa89866bd..eabbc8351 100644
--- a/src/sim/system.hh
+++ b/src/sim/system.hh
@@ -45,6 +45,7 @@
#include "mem/port.hh"
#include "params/System.hh"
#include "sim/sim_object.hh"
+
#if FULL_SYSTEM
#include "kern/system_events.hh"
#include "mem/vport.hh"
@@ -59,10 +60,7 @@ class PhysicalMemory;
class Platform;
#endif
class GDBListener;
-namespace TheISA
-{
- class RemoteGDB;
-}
+class BaseRemoteGDB;
class System : public SimObject
{
@@ -187,7 +185,7 @@ class System : public SimObject
#endif
public:
- std::vector<TheISA::RemoteGDB *> remoteGDB;
+ std::vector<BaseRemoteGDB *> remoteGDB;
std::vector<GDBListener *> gdbListen;
bool breakpoint();