Merge branch 'default' into kernigh-osx
This brings in David Given's PowerPC changes, including the addition of the modern code generator (mcg) for PowerPC. Resolve minor conflicts in top build.lua and util/led/main.c
This commit is contained in:
commit
ecdfb61c9d
|
@ -1,12 +1,13 @@
|
|||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
- os: osx
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- ed
|
||||
- openbios-ppc
|
||||
- qemu-user
|
||||
|
||||
git:
|
||||
depth: 10
|
||||
|
|
17
README
17
README
|
@ -2,7 +2,7 @@
|
|||
===================================
|
||||
|
||||
© 1987-2005 Vrije Universiteit, Amsterdam
|
||||
2016-08-02
|
||||
2016-11-26
|
||||
|
||||
|
||||
INTRODUCTION
|
||||
|
@ -19,6 +19,7 @@ probably broken. However, what's there should be sufficient to get things
|
|||
done and to evaluate how the full 6.1 release should work.
|
||||
|
||||
|
||||
|
||||
SUPPORT
|
||||
=======
|
||||
|
||||
|
@ -31,10 +32,12 @@ Platforms:
|
|||
pc86 produces bootable floppy disk images for 8086 PCs
|
||||
linux386 produces ELF executables for PC Linux systems
|
||||
linux68k produces ELF executables for m68020 Linux systems
|
||||
linuxppc produces ELF executables for PowerPC Linux systems
|
||||
cpm produces i80 CP/M .COM files
|
||||
rpi produces Raspberry Pi GPU binaries
|
||||
|
||||
|
||||
|
||||
INSTALLATION
|
||||
============
|
||||
|
||||
|
@ -55,6 +58,11 @@ Requirements:
|
|||
- (optionally) ninja; if you've got this, this will be autodetected and give
|
||||
you faster builds.
|
||||
|
||||
- (optionally) the qemu suite: if you have this installed, the build system
|
||||
will detect it automatically and run the test suites for the supported
|
||||
architectures. Get both the qemu-system-* platform emulators and the qemu-*
|
||||
userland emulators (only works on Linux).
|
||||
|
||||
- about 40MB free in /tmp (or some other temporary directory).
|
||||
|
||||
- about 6MB in the target directory.
|
||||
|
@ -89,6 +97,7 @@ Instructions:
|
|||
The ACK should now be ready to use.
|
||||
|
||||
|
||||
|
||||
USAGE
|
||||
=====
|
||||
|
||||
|
@ -155,6 +164,8 @@ There are some things you should be aware of.
|
|||
interpreter and the assembler-linkers. Only some of it builds. Look for
|
||||
build.lua files.
|
||||
|
||||
|
||||
|
||||
DISCLAIMER
|
||||
==========
|
||||
|
||||
|
@ -177,6 +188,6 @@ You can find the mailing list on the project's web site:
|
|||
|
||||
Please enjoy.
|
||||
|
||||
David Given (dtrg on Sourceforge)
|
||||
David Given (davidgiven on Github)
|
||||
dg@cowlark.com
|
||||
2016-08-02
|
||||
2016-11-26
|
||||
|
|
14
build.lua
14
build.lua
|
@ -11,14 +11,25 @@ vars.plats = {
|
|||
"linuxppc",
|
||||
"osx386",
|
||||
"osxppc",
|
||||
"qemuppc",
|
||||
"pc86",
|
||||
"rpi",
|
||||
}
|
||||
vars.plats_with_tests = {
|
||||
"linux386",
|
||||
"linuxppc",
|
||||
"qemuppc",
|
||||
"pc86",
|
||||
}
|
||||
|
||||
local plat_packages = {}
|
||||
local test_packages = {}
|
||||
for _, p in ipairs(vars.plats) do
|
||||
plat_packages[#plat_packages+1] = "plat/"..p.."+pkg"
|
||||
end
|
||||
for _, p in ipairs(vars.plats_with_tests) do
|
||||
test_packages[#test_packages+1] = "plat/"..p.."/tests+tests"
|
||||
end
|
||||
|
||||
installable {
|
||||
name = "ack",
|
||||
|
@ -36,6 +47,9 @@ installable {
|
|||
"util/opt+pkg",
|
||||
"examples+pkg",
|
||||
plat_packages
|
||||
},
|
||||
deps = {
|
||||
test_packages
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
This is a public domain adventure and may not be sold for profit */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define MOXIE 13
|
||||
|
@ -32,7 +33,9 @@ int plato_clone=3;
|
|||
int blast_door=0;
|
||||
int killer_count=0;
|
||||
|
||||
char get_char()
|
||||
void character(void);
|
||||
|
||||
char get_char(void)
|
||||
{
|
||||
char c;
|
||||
fflush(stdout);
|
||||
|
@ -41,7 +44,7 @@ char get_char()
|
|||
return c;
|
||||
}
|
||||
|
||||
more()
|
||||
void more(void)
|
||||
{
|
||||
printf("---------- More ----------");
|
||||
#ifdef DEBUG
|
||||
|
@ -55,8 +58,7 @@ more()
|
|||
};
|
||||
}
|
||||
|
||||
new_clone(resume)
|
||||
int resume;
|
||||
int new_clone(int resume)
|
||||
{
|
||||
printf("\nClone %d just died.\n",clone);
|
||||
if (++clone>6)
|
||||
|
@ -75,15 +77,14 @@ int resume;
|
|||
}
|
||||
}
|
||||
|
||||
dice_roll(number,faces)
|
||||
int number, faces;
|
||||
int dice_roll(int number, int faces)
|
||||
{
|
||||
int i,total=0;
|
||||
for(i=number;i>0;i--) total+= rand()%faces+1;
|
||||
return total;
|
||||
}
|
||||
|
||||
instructions()
|
||||
void instructions(void)
|
||||
{
|
||||
printf("\n\n\n\nWelcome to Paranoia!\n\n");
|
||||
printf("HOW TO PLAY:\n\n");
|
||||
|
@ -104,7 +105,7 @@ instructions()
|
|||
printf(" If not, you can try again later.\n");
|
||||
}
|
||||
|
||||
character()
|
||||
void character(void)
|
||||
{
|
||||
printf("===============================================================================\n");
|
||||
printf("The Character : Philo-R-DMD %d\n", clone);
|
||||
|
@ -130,9 +131,7 @@ character()
|
|||
printf("===============================================================================\n");
|
||||
}
|
||||
|
||||
choose(a,aptr,b,bptr)
|
||||
int a,b;
|
||||
char *aptr, *bptr;
|
||||
int choose(int a, char* aptr, int b, char* bptr)
|
||||
{
|
||||
printf("\nSelect \'a\' or \'b\' :\n");
|
||||
printf(" a - %s.\n b - %s.\n", aptr, bptr);
|
||||
|
@ -140,7 +139,7 @@ char *aptr, *bptr;
|
|||
else return b;
|
||||
}
|
||||
|
||||
page1()
|
||||
int page1(void)
|
||||
{
|
||||
printf(" You wake up face down on the red and pink checked E-Z-Kleen linoleum floor.\n");
|
||||
printf(" You recognise the pattern, it\'s the type preferred in the internal security\nbriefing cells. When you finally look around you, you see that you are alone\n");
|
||||
|
@ -148,7 +147,7 @@ page1()
|
|||
return 57;
|
||||
}
|
||||
|
||||
page2()
|
||||
int page2(void)
|
||||
{
|
||||
printf("\"Greetings,\" says the kindly Internal Security self incrimination expert who\n");
|
||||
printf("meets you at the door, \"How are we doing today?\" He offers you a doughnut\n");
|
||||
|
@ -166,7 +165,7 @@ page2()
|
|||
else return new_clone(32);
|
||||
}
|
||||
|
||||
page3()
|
||||
int page3(void)
|
||||
{
|
||||
printf("You walk to the nearest Computer terminal and request more information about\n");
|
||||
printf("Christmas. The Computer says, \"That is an A-1 ULTRAVIOLET ONLY IMMEDIATE\n");
|
||||
|
@ -174,7 +173,7 @@ page3()
|
|||
return choose(4,"You give your correct clearance",5,"You lie and claim Ultraviolet clearance");
|
||||
}
|
||||
|
||||
page4()
|
||||
int page4(void)
|
||||
{
|
||||
printf("\"That is classified information, Troubleshooter, thank you for your inquiry.\n");
|
||||
printf(" Please report to an Internal Security self incrimination station as soon as\n");
|
||||
|
@ -182,7 +181,7 @@ page4()
|
|||
return 9;
|
||||
}
|
||||
|
||||
page5()
|
||||
int page5(void)
|
||||
{
|
||||
printf("The computer says, \"Troubleshooter, you are not wearing the correct colour\n");
|
||||
printf("uniform. You must put on an Ultraviolet uniform immediately. I have seen to\n");
|
||||
|
@ -193,7 +192,7 @@ page5()
|
|||
return choose(6, "You open the package and put on the uniform", 7, "You finally come to your senses and run for it");
|
||||
}
|
||||
|
||||
page6()
|
||||
int page6(void)
|
||||
{
|
||||
printf("The uniform definitely makes you look snappy and pert. It really looks\n");
|
||||
printf("impressive, and even has the new lopsided lapel fashion that you admire so\n");
|
||||
|
@ -205,7 +204,7 @@ page6()
|
|||
return 8;
|
||||
}
|
||||
|
||||
page7()
|
||||
int page7(void)
|
||||
{
|
||||
printf("The corridor lights dim and are replaced by red battle lamps as the Security\n");
|
||||
printf("Breach alarms howl all around you. You run headlong down the corridor and\n");
|
||||
|
@ -232,7 +231,7 @@ page7()
|
|||
return 8;
|
||||
}
|
||||
|
||||
page8()
|
||||
int page8(void)
|
||||
{
|
||||
printf("\"Now, about your question, citizen. Christmas was an old world marketing ploy\n");
|
||||
printf("to induce lower clearance citizens to purchase vast quantities of goods, thus\n");
|
||||
|
@ -249,7 +248,7 @@ page8()
|
|||
return 10;
|
||||
}
|
||||
|
||||
page9()
|
||||
int page9(void)
|
||||
{
|
||||
int choice;
|
||||
printf("As you walk toward the tubecar that will take you to GDH7-beta, you pass one\n");
|
||||
|
@ -262,7 +261,7 @@ page9()
|
|||
return choice;
|
||||
}
|
||||
|
||||
page10()
|
||||
int page10(void)
|
||||
{
|
||||
int choice;
|
||||
printf("You stroll briskly down the corridor, up a ladder, across an unrailed catwalk,\n");
|
||||
|
@ -290,7 +289,7 @@ page10()
|
|||
}
|
||||
}
|
||||
|
||||
page11()
|
||||
int page11(void)
|
||||
{
|
||||
printf("The printing on the folder says \"Experimental Self Briefing.\"\n");
|
||||
printf("You open it and begin to read the following:\n");
|
||||
|
@ -321,7 +320,7 @@ page11()
|
|||
return choose(3,"You wish to ask The Computer for more information about Christmas",10,"You have decided to go directly to Goods Distribution Hall 7-beta");
|
||||
}
|
||||
|
||||
page12()
|
||||
int page12(void)
|
||||
{
|
||||
printf("You walk up to the door and push the button labelled \"push to exit.\"\n");
|
||||
printf("Within seconds a surly looking guard shoves his face into the small plexiglass\n");
|
||||
|
@ -333,7 +332,7 @@ page12()
|
|||
return choose(11,"You sit down at the table and read the Orange packet",57,"You stare around the room some more");
|
||||
}
|
||||
|
||||
page13()
|
||||
int page13(void)
|
||||
{
|
||||
printf("You step into the shiny plasteel tubecar, wondering why the shape has always\n");
|
||||
printf("reminded you of bullets. The car shoots forward the instant your feet touch\n");
|
||||
|
@ -346,7 +345,7 @@ page13()
|
|||
return 14;
|
||||
}
|
||||
|
||||
page14()
|
||||
int page14(void)
|
||||
{
|
||||
printf("You manage to pull yourself out of the tubecar and look around. Before you is\n");
|
||||
printf("one of the most confusing things you have ever seen, a hallway that is\n");
|
||||
|
@ -360,7 +359,7 @@ page14()
|
|||
return 22;
|
||||
}
|
||||
|
||||
page15()
|
||||
int page15(void)
|
||||
{
|
||||
printf("You are set upon by a runty robot with a queer looking face and two pointy\n");
|
||||
printf("rubber ears poking from beneath a tattered cap. \"Hey mister,\" it says,\n");
|
||||
|
@ -384,7 +383,7 @@ page15()
|
|||
}
|
||||
}
|
||||
|
||||
page16()
|
||||
int page16(void)
|
||||
{
|
||||
printf("The doll is a good buy for fifty credits; it will make a fine Christmas present\n");
|
||||
printf("for one of your friends. After the sale the robot rolls away. You can use\n");
|
||||
|
@ -395,7 +394,7 @@ page16()
|
|||
return 22;
|
||||
}
|
||||
|
||||
page17()
|
||||
int page17(void)
|
||||
{
|
||||
int i, robot_hp=15;
|
||||
printf("You whip out your laser and shoot the robot, but not before it squeezes the\n");
|
||||
|
@ -432,7 +431,7 @@ page17()
|
|||
return 22;
|
||||
}
|
||||
|
||||
page18()
|
||||
int page18(void)
|
||||
{
|
||||
printf("You walk to the centre of the hall, ogling like an infrared fresh from the\n");
|
||||
printf("clone vats. Towering before you is the most unearthly thing you have ever\n");
|
||||
|
@ -448,7 +447,7 @@ page18()
|
|||
else return 20;
|
||||
}
|
||||
|
||||
page19()
|
||||
int page19(void)
|
||||
{
|
||||
printf("Quickly you regain your balance, whirl and fire your laser into the Ultraviolet\n");
|
||||
printf("citizen behind you. For a moment your heart leaps to your throat, then you\n");
|
||||
|
@ -461,7 +460,7 @@ page19()
|
|||
return choose(34,"You search the body, keeping an eye open for Internal Security",22,"You run away like the cowardly dog you are");
|
||||
}
|
||||
|
||||
page20()
|
||||
int page20(void)
|
||||
{
|
||||
printf("Oh no! you can\'t keep your balance. You\'re falling, falling head first into\n");
|
||||
printf("the Christmas beast\'s gaping maw. It\'s a valiant struggle; you think you are\n");
|
||||
|
@ -473,7 +472,7 @@ page20()
|
|||
return 22;
|
||||
}
|
||||
|
||||
page21()
|
||||
int page21(void)
|
||||
{
|
||||
printf("You have been wasting the leading citizens of Alpha Complex at a prodigious\n");
|
||||
printf("rate. This has not gone unnoticed by the Internal Security squad at GDH7-beta.\n");
|
||||
|
@ -482,7 +481,7 @@ page21()
|
|||
return new_clone(45);
|
||||
}
|
||||
|
||||
page22()
|
||||
int page22(void)
|
||||
{
|
||||
printf("You are searching Goods Distribution Hall 7-beta.\n");
|
||||
switch(dice_roll(1,4))
|
||||
|
@ -494,7 +493,7 @@ page22()
|
|||
}
|
||||
}
|
||||
|
||||
page23()
|
||||
int page23(void)
|
||||
{
|
||||
printf("You go to the nearest computer terminal and declare yourself a mutant.\n");
|
||||
printf("\"A mutant, he\'s a mutant,\" yells a previously unnoticed infrared who had\n");
|
||||
|
@ -503,7 +502,7 @@ page23()
|
|||
return choose(28,"You tell them that it was really only a bad joke",24,"You want to fight it out, one against twelve");
|
||||
}
|
||||
|
||||
page24()
|
||||
int page24(void)
|
||||
{
|
||||
printf("Golly, I never expected someone to pick this. I haven\'t even designed\n");
|
||||
printf("the 12 citizens who are going to make a sponge out of you. Tell you what,\n");
|
||||
|
@ -511,7 +510,7 @@ page24()
|
|||
return choose(28,"You change your mind and say it was only a bad joke",25,"You REALLY want to shoot it out");
|
||||
}
|
||||
|
||||
page25()
|
||||
int page25(void)
|
||||
{
|
||||
printf("Boy, you really can\'t take a hint!\n");
|
||||
printf("They\'re closing in. Their trigger fingers are twitching, they\'re about to\n");
|
||||
|
@ -519,7 +518,7 @@ page25()
|
|||
return choose(28,"You tell them it was all just a bad joke",26,"You are going to shoot");
|
||||
}
|
||||
|
||||
page26()
|
||||
int page26(void)
|
||||
{
|
||||
printf("You can read the cold, sober hatred in their eyes (They really didn\'t think\n");
|
||||
printf("it was funny), as they tighten the circle around you. One of them shoves a\n");
|
||||
|
@ -529,19 +528,19 @@ page26()
|
|||
return new_clone(32);
|
||||
}
|
||||
|
||||
page27()
|
||||
int page27(void)
|
||||
{
|
||||
/* doesn't exist. Can't happen with computer version.
|
||||
designed to catch dice cheats */
|
||||
}
|
||||
|
||||
page28()
|
||||
int page28(void)
|
||||
{
|
||||
printf("They don\'t think it\'s funny.\n");
|
||||
return 26;
|
||||
}
|
||||
|
||||
page29()
|
||||
int page29(void)
|
||||
{
|
||||
printf("\"Psst, hey citizen, come here. Pssfft,\" you hear. When you peer around\n");
|
||||
printf("you can see someone\'s dim outline in the shadows. \"I got some information\n");
|
||||
|
@ -559,7 +558,7 @@ page29()
|
|||
}
|
||||
}
|
||||
|
||||
page30()
|
||||
int page30(void)
|
||||
{
|
||||
printf("You step into the shadows and offer the man a thirty credit bill. \"Just drop\n");
|
||||
printf("it on the floor,\" he says. \"So you\'re looking for the Master Retailer, pssfft?\n");
|
||||
|
@ -586,7 +585,7 @@ page30()
|
|||
}
|
||||
}
|
||||
|
||||
page31()
|
||||
int page31(void)
|
||||
{
|
||||
printf("Like any good troubleshooter you make the least expensive decision and threaten\n");
|
||||
printf("him for information. With lightning like reflexes you whip out your laser and\n");
|
||||
|
@ -599,7 +598,7 @@ page31()
|
|||
return choose(30,"You pay the 30 credits",22,"You pssfft go away stupid");
|
||||
}
|
||||
|
||||
page32()
|
||||
int page32(void)
|
||||
{
|
||||
printf("Finally it\'s your big chance to prove that you\'re as good a troubleshooter\n");
|
||||
printf("as your previous clone. You walk briskly to mission briefing and pick up your\n");
|
||||
|
@ -609,7 +608,7 @@ page32()
|
|||
return 22;
|
||||
}
|
||||
|
||||
page33()
|
||||
int page33(void)
|
||||
{
|
||||
blast_door=1;
|
||||
printf("You release the megabolts on the blast door, then strain against it with your\n");
|
||||
|
@ -622,7 +621,7 @@ page33()
|
|||
else return 36;
|
||||
}
|
||||
|
||||
page34()
|
||||
int page34(void)
|
||||
{
|
||||
printf("You have found a sealed envelope on the body. You open it and read:\n");
|
||||
printf("\"WARNING: Ultraviolet Clearance ONLY. DO NOT READ.\n");
|
||||
|
@ -650,7 +649,7 @@ page34()
|
|||
return choose(46,"You rush off to the nearest computer terminal to expose the commies",22,"You wander off to look for more evidence");
|
||||
}
|
||||
|
||||
page35()
|
||||
int page35(void)
|
||||
{
|
||||
printf("\"Oh master,\" you hear through the gun barrel, \"where have you been? It is\n");
|
||||
printf("time for the great Christmas gifting ceremony. You had better hurry and get\n");
|
||||
|
@ -669,7 +668,7 @@ page35()
|
|||
return new_clone(32);
|
||||
}
|
||||
|
||||
page36()
|
||||
int page36(void)
|
||||
{
|
||||
printf("\"Congratulations, troubleshooter, you have successfully found the lair of the\n");
|
||||
printf("Master Retailer and completed the Troubleshooter Training Course test mission,\"\n");
|
||||
|
@ -692,7 +691,7 @@ page36()
|
|||
}
|
||||
}
|
||||
|
||||
page37()
|
||||
int page37(void)
|
||||
{
|
||||
printf("\"Come with me please, Troubleshooter,\" says the Green clearance technician\n");
|
||||
printf("after he has dislodged your head from the cannon. \"You have been participating\n");
|
||||
|
@ -708,7 +707,7 @@ page37()
|
|||
return 38;
|
||||
}
|
||||
|
||||
page38()
|
||||
int page38(void)
|
||||
{
|
||||
printf("\"I am Plato-B-PHI%d, head of mutant propaganda here at the training course.\n",plato_clone);
|
||||
printf("If you have any questions about mutants please come to me. Today I will be\n");
|
||||
|
@ -725,7 +724,7 @@ page38()
|
|||
return choose(39,"You volunteer for the test",40,"You duck behind a chair and hope the instructor doesn\'t notice you");
|
||||
}
|
||||
|
||||
page39()
|
||||
int page39(void)
|
||||
{
|
||||
printf("You bravely volunteer to test the mutant detection gun. You stand up and walk\n");
|
||||
printf("down the steps to the podium, passing a very relieved Troubleshooter along the\n");
|
||||
|
@ -743,7 +742,7 @@ page39()
|
|||
return 41;
|
||||
}
|
||||
|
||||
page40()
|
||||
int page40(void)
|
||||
{
|
||||
printf("You breathe a sigh of relief as Plato-B-PHI picks on the other Troubleshooter.\n");
|
||||
printf("\"You down here in the front,\" says the instructor pointing at the other\n");
|
||||
|
@ -775,7 +774,7 @@ page40()
|
|||
}
|
||||
}
|
||||
|
||||
page41()
|
||||
int page41(void)
|
||||
{
|
||||
printf("You stumble down the hallway of the Troubleshooter Training Course looking for\n");
|
||||
printf("your next class. Up ahead you see one of the instructors waving to you. When\n");
|
||||
|
@ -789,7 +788,7 @@ page41()
|
|||
return choose(42,"You respond with the proper Illuminati code phrase, \"Ewige Blumenkraft\"",43,"You ignore this secret society contact");
|
||||
}
|
||||
|
||||
page42()
|
||||
int page42(void)
|
||||
{
|
||||
printf("\"Aha, so you are a member of the elitist Illuminati secret society,\" he says\n");
|
||||
printf("loudly, \"that is most interesting.\" He turns to the large class already\n");
|
||||
|
@ -799,7 +798,7 @@ page42()
|
|||
return choose(51,"You run for it",52,"You wait for the guard");
|
||||
}
|
||||
|
||||
page43()
|
||||
int page43(void)
|
||||
{
|
||||
printf("You sit through a long lecture on how to recognise and infiltrate secret\n");
|
||||
printf("societies, with an emphasis on mimicking secret handshakes. The basic theory,\n");
|
||||
|
@ -815,7 +814,7 @@ page43()
|
|||
return choose(44,"You go looking for a computer terminal",55,"You go to the graduation ceremony immediately");
|
||||
}
|
||||
|
||||
page44()
|
||||
int page44(void)
|
||||
{
|
||||
printf("You walk down to a semi-secluded part of the training course complex and\n");
|
||||
printf("activate a computer terminal. \"AT YOUR SERVICE\" reads the computer screen.\n");
|
||||
|
@ -833,7 +832,7 @@ page44()
|
|||
}
|
||||
}
|
||||
|
||||
page45()
|
||||
int page45(void)
|
||||
{
|
||||
printf("\"Hrank Hrank,\" snorts the alarm in your living quarters. Something is up.\n");
|
||||
printf("You look at the monitor above the bathroom mirror and see the message you have\n");
|
||||
|
@ -847,7 +846,7 @@ page45()
|
|||
return 10;
|
||||
}
|
||||
|
||||
page46()
|
||||
int page46(void)
|
||||
{
|
||||
printf("\"Why do you ask about the communists, Troubleshooter? It is not in the\n");
|
||||
printf("interest of your continued survival to be asking about such topics,\" says\n");
|
||||
|
@ -855,7 +854,7 @@ page46()
|
|||
return choose(53,"You insist on talking about the communists",54,"You change the subject");
|
||||
}
|
||||
|
||||
page47()
|
||||
int page47(void)
|
||||
{
|
||||
printf("The Computer orders the entire Vulture squadron to terminate the Troubleshooter\n");
|
||||
printf("Training Course. Unfortunately you too are terminated for possessing\n");
|
||||
|
@ -867,7 +866,7 @@ page47()
|
|||
return 0;
|
||||
}
|
||||
|
||||
page48()
|
||||
int page48(void)
|
||||
{
|
||||
printf("The tubecar shoots forward as you enter, slamming you back into a pile of\n");
|
||||
printf("garbage. The front end rotates upward and you, the garbage and the garbage\n");
|
||||
|
@ -877,14 +876,14 @@ page48()
|
|||
return new_clone(45);
|
||||
}
|
||||
|
||||
page49()
|
||||
int page49(void)
|
||||
{
|
||||
printf("The instructor drags your inert body into a specimen detainment cage.\n");
|
||||
printf("\"He\'ll make a good subject for tomorrow\'s mutant dissection class,\" you hear.\n");
|
||||
return new_clone(32);
|
||||
}
|
||||
|
||||
page50()
|
||||
int page50(void)
|
||||
{
|
||||
printf("You put down the other Troubleshooter, and then wisely decide to drill a few\n");
|
||||
printf("holes in the instructor as well; the only good witness is a dead witness.\n");
|
||||
|
@ -893,27 +892,27 @@ page50()
|
|||
return 41;
|
||||
}
|
||||
|
||||
page51()
|
||||
int page51(void)
|
||||
{
|
||||
printf("You run for it, but you don\'t run far. Three hundred strange and exotic\n");
|
||||
printf("weapons turn you into a freeze dried cloud of soot.\n");
|
||||
return new_clone(32);
|
||||
}
|
||||
|
||||
page52()
|
||||
int page52(void)
|
||||
{
|
||||
printf("You wisely wait until the instructor returns with a Blue Internal Security\n");
|
||||
printf("guard. The guard leads you to an Internal Security self incrimination station.\n");
|
||||
return 2;
|
||||
}
|
||||
|
||||
page53()
|
||||
int page53(void)
|
||||
{
|
||||
printf("You tell The Computer about:\n");
|
||||
return choose(47,"The commies who have infiltrated the Troubleshooter Training Course\n and the impending People\'s Revolution",54,"Something less dangerous");
|
||||
}
|
||||
|
||||
page54()
|
||||
int page54(void)
|
||||
{
|
||||
printf("\"Do not try to change the subject, Troubleshooter,\" says The Computer.\n");
|
||||
printf("\"It is a serious crime to ask about the communists. You will be terminated\n");
|
||||
|
@ -927,7 +926,7 @@ page54()
|
|||
else return new_clone(32);
|
||||
}
|
||||
|
||||
page55()
|
||||
int page55(void)
|
||||
{
|
||||
printf("You and 300 other excited graduates are marched from the lecture hall and into\n");
|
||||
printf("a large auditorium for the graduation exercise. The auditorium is\n");
|
||||
|
@ -955,7 +954,7 @@ page55()
|
|||
return 0;
|
||||
}
|
||||
|
||||
page56()
|
||||
int page56(void)
|
||||
{
|
||||
printf("That familiar strange feeling of deja\'vu envelops you again. It is hard to\n");
|
||||
printf("say, but whatever is on the other side of the door does not seem to be intended\n");
|
||||
|
@ -963,15 +962,14 @@ page56()
|
|||
return choose(33,"You open the door and step through",22,"You go looking for more information");
|
||||
}
|
||||
|
||||
page57()
|
||||
int page57(void)
|
||||
{
|
||||
printf("In the centre of the room is a table and a single chair. There is an Orange\n");
|
||||
printf("folder on the table top, but you can\'t make out the lettering on it.\n");
|
||||
return choose(11,"You sit down and read the folder",12,"You leave the room");
|
||||
}
|
||||
|
||||
next_page(this_page)
|
||||
int this_page;
|
||||
int next_page(int this_page)
|
||||
{
|
||||
printf("\n");
|
||||
switch (this_page)
|
||||
|
@ -1038,10 +1036,11 @@ int this_page;
|
|||
}
|
||||
}
|
||||
|
||||
main()
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
/* srand(time(0)); */
|
||||
instructions(); more();
|
||||
character(); more();
|
||||
while((page=next_page(page))!=0) more();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -451,7 +451,7 @@ loadtarget = function(targetname)
|
|||
target = targets[targetname]
|
||||
if not target then
|
||||
error(string.format("build file '%s' contains no target '%s'",
|
||||
filename, targetpart))
|
||||
filepart, targetpart))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -729,9 +729,10 @@ definerule("simplerule",
|
|||
definerule("installable",
|
||||
{
|
||||
map = { type="targets", default={} },
|
||||
deps = { type="targets", default={} },
|
||||
},
|
||||
function (e)
|
||||
local deps = {}
|
||||
local deps = filenamesof(e.deps)
|
||||
local commands = {}
|
||||
local srcs = {}
|
||||
local outs = {}
|
||||
|
|
|
@ -226,6 +226,7 @@ definerule("cprogram",
|
|||
},
|
||||
function (e)
|
||||
local libs = matching(filenamesof(e.deps), "%.a$")
|
||||
local srcs = {}
|
||||
if (#e.srcs > 0) then
|
||||
for _, f in pairs(
|
||||
matching(
|
||||
|
@ -240,7 +241,7 @@ definerule("cprogram",
|
|||
"%.a$"
|
||||
)
|
||||
) do
|
||||
libs[#libs+1] = f
|
||||
srcs[#srcs+1] = f
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -248,7 +249,7 @@ definerule("cprogram",
|
|||
name = e.name,
|
||||
cwd = e.cwd,
|
||||
deps = e.deps,
|
||||
ins = libs,
|
||||
ins = { srcs, libs },
|
||||
outleaves = { e.name },
|
||||
commands = e.commands,
|
||||
}
|
||||
|
|
|
@ -702,6 +702,7 @@ static int Pgetpid(lua_State *L) /** getpid([options]) */
|
|||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static int Phostid(lua_State *L) /** hostid() */
|
||||
{
|
||||
char b[32];
|
||||
|
@ -709,6 +710,7 @@ static int Phostid(lua_State *L) /** hostid() */
|
|||
lua_pushstring(L, b);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int Pttyname(lua_State *L) /** ttyname([fd]) */
|
||||
|
@ -1060,7 +1062,7 @@ static const luaL_reg R[] =
|
|||
{"getpasswd", Pgetpasswd},
|
||||
{"getpid", Pgetpid},
|
||||
{"glob", Pglob},
|
||||
{"hostid", Phostid},
|
||||
//{"hostid", Phostid},
|
||||
{"kill", Pkill},
|
||||
{"link", Plink},
|
||||
{"mkdir", Pmkdir},
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int _errsym;
|
||||
int _erlsym;
|
||||
|
||||
/* error takes an error value in the range of 0-255 */
|
||||
/* and generates a trap */
|
||||
|
||||
|
@ -52,9 +55,6 @@ char *errortable[255]={
|
|||
error(index)
|
||||
int index;
|
||||
{
|
||||
extern int _errsym;
|
||||
extern int _erlsym;
|
||||
|
||||
_setline();
|
||||
if( index<0 || index >40 )
|
||||
printf("LINE %d:ERROR %d: Unprintable error\n",_erlsym,index);
|
||||
|
|
|
@ -31,6 +31,7 @@ int ltype,rtype;
|
|||
|
||||
|
||||
|
||||
void
|
||||
conversion(oldtype,newtype)
|
||||
int oldtype,newtype;
|
||||
{
|
||||
|
@ -71,6 +72,7 @@ int oldtype,newtype;
|
|||
|
||||
|
||||
|
||||
void
|
||||
extraconvert(oldtype,newtype,topstack)
|
||||
int oldtype,newtype,topstack;
|
||||
{
|
||||
|
@ -509,6 +511,7 @@ endarrayload()
|
|||
|
||||
|
||||
|
||||
void
|
||||
loadarray(type)
|
||||
int type;
|
||||
{
|
||||
|
|
|
@ -617,11 +617,7 @@ prologcode()
|
|||
C_df_dnam("_iomode");
|
||||
C_rom_scon("O",(arith)2);
|
||||
C_exa_dnam("_errsym");
|
||||
C_df_dnam("_errsym");
|
||||
C_bss_cst((arith)BEMINTSIZE,(arith)0,1);
|
||||
C_exa_dnam("_erlsym");
|
||||
C_df_dnam("_erlsym");
|
||||
C_bss_cst((arith)BEMINTSIZE,(arith)0,1);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ char *str;
|
|||
|
||||
|
||||
|
||||
void
|
||||
dcltype(s)
|
||||
Symbol *s;
|
||||
{
|
||||
|
|
|
@ -16,6 +16,7 @@ int errorcnt;
|
|||
|
||||
|
||||
|
||||
void
|
||||
warning(str)
|
||||
char *str;
|
||||
{
|
||||
|
|
|
@ -52,6 +52,8 @@ extern int lint_skip_comment;
|
|||
static struct token LexStack[MAX_LL_DEPTH];
|
||||
static LexSP = 0;
|
||||
|
||||
void skipcomment();
|
||||
|
||||
/* In PushLex() the actions are taken in order to initialise or
|
||||
re-initialise the lexical scanner.
|
||||
E.g. at the invocation of a sub-parser that uses LLlex(), the
|
||||
|
@ -442,6 +444,7 @@ garbage:
|
|||
}
|
||||
|
||||
#ifndef NOPP
|
||||
void
|
||||
skipcomment()
|
||||
{
|
||||
/* The last character read has been the '*' of '/_*'. The
|
||||
|
|
|
@ -30,6 +30,7 @@ extern char options[];
|
|||
extern arith flt_flt2arith();
|
||||
extern label code_string();
|
||||
|
||||
void
|
||||
arithbalance(e1p, oper, e2p) /* 3.1.2.5 */
|
||||
register struct expr **e1p, **e2p;
|
||||
int oper;
|
||||
|
@ -523,6 +524,7 @@ opnd2logical(expp, oper)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
opnd2test(expp, oper)
|
||||
register struct expr **expp;
|
||||
{
|
||||
|
@ -548,6 +550,7 @@ opnd2test(expp, oper)
|
|||
ch3bin(expp, NOTEQUAL, intexpr((arith)0, INT));
|
||||
}
|
||||
|
||||
void
|
||||
any2opnd(expp, oper)
|
||||
register struct expr **expp;
|
||||
{
|
||||
|
|
|
@ -23,11 +23,14 @@ extern char options[];
|
|||
extern char *symbol2str();
|
||||
extern struct type *qualifier_type();
|
||||
|
||||
void ch3cast();
|
||||
|
||||
/* Most expression-handling routines have a pointer to a
|
||||
(struct type *) as first parameter. The object under the pointer
|
||||
gets updated in the process.
|
||||
*/
|
||||
|
||||
void
|
||||
ch3sel(expp, oper, idf)
|
||||
struct expr **expp;
|
||||
struct idf *idf;
|
||||
|
@ -169,6 +172,7 @@ ch3incr(expp, oper)
|
|||
ch3asgn(expp, oper, intexpr((arith)1, INT));
|
||||
}
|
||||
|
||||
void
|
||||
ch3cast(expp, oper, tp)
|
||||
register struct expr **expp;
|
||||
register struct type *tp;
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
extern char options[];
|
||||
extern char *symbol2str();
|
||||
|
||||
void pntminuspnt();
|
||||
|
||||
/* This chapter asks for the repeated application of code to handle
|
||||
an operation that may be executed at compile time or at run time,
|
||||
depending on the constancy of the operands.
|
||||
|
@ -32,6 +34,7 @@ extern char *symbol2str();
|
|||
#define commutative_binop(expp, oper, expr) mk_binop(expp, oper, expr, 1)
|
||||
#define non_commutative_relop(expp, oper, expr) mk_binop(expp, oper, expr, 1)
|
||||
|
||||
void
|
||||
ch3bin(expp, oper, expr)
|
||||
register struct expr **expp;
|
||||
struct expr *expr;
|
||||
|
@ -292,6 +295,7 @@ ch3bin(expp, oper, expr)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
pntminuspnt(expp, oper, expr)
|
||||
register struct expr **expp, *expr;
|
||||
{
|
||||
|
|
|
@ -64,6 +64,8 @@ extern char options[];
|
|||
extern char *symbol2str();
|
||||
extern char *source;
|
||||
|
||||
void loc_init();
|
||||
|
||||
#ifndef LINT
|
||||
init_code(dst_file)
|
||||
char *dst_file;
|
||||
|
@ -415,6 +417,7 @@ do_return_expr(expr)
|
|||
return_expr_occurred = 1;
|
||||
}
|
||||
|
||||
void
|
||||
code_declaration(idf, expr, lvl, sc)
|
||||
register struct idf *idf; /* idf to be declared */
|
||||
struct expr *expr; /* initialisation; NULL if absent */
|
||||
|
@ -527,6 +530,7 @@ code_declaration(idf, expr, lvl, sc)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
loc_init(expr, id)
|
||||
struct expr *expr;
|
||||
struct idf *id;
|
||||
|
@ -721,6 +725,7 @@ code_break()
|
|||
it generates a branch instruction to the continue label of the
|
||||
innermost statement in which continue has a meaning.
|
||||
*/
|
||||
void
|
||||
code_continue()
|
||||
{
|
||||
register struct stmt_block *stmt_block = stmt_stack;
|
||||
|
|
|
@ -34,6 +34,9 @@ char ifstack[IFDEPTH]; /* if-stack: the content of an entry is */
|
|||
|
||||
int nestlevel = -1;
|
||||
|
||||
void macro_def();
|
||||
void do_define();
|
||||
|
||||
struct idf *
|
||||
GetIdentifier(skiponerr)
|
||||
int skiponerr; /* skip the rest of the line on error */
|
||||
|
@ -145,6 +148,7 @@ domacro()
|
|||
int lint_skip_comment;
|
||||
#endif
|
||||
|
||||
void
|
||||
skip_block(to_endif)
|
||||
int to_endif;
|
||||
{
|
||||
|
@ -347,6 +351,7 @@ do_include()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
do_define()
|
||||
{
|
||||
/* do_define() interprets a #define control line.
|
||||
|
@ -574,6 +579,7 @@ getparams(buf, parbuf)
|
|||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
void
|
||||
macro_def(id, text, nformals, length, flags)
|
||||
register struct idf *id;
|
||||
char *text;
|
||||
|
|
|
@ -57,7 +57,7 @@ extern char loptions[];
|
|||
expression, whereas other errors use the information in the token.
|
||||
*/
|
||||
|
||||
static _error();
|
||||
static void _error();
|
||||
|
||||
#if __STDC__
|
||||
/*VARARGS*/
|
||||
|
@ -521,7 +521,7 @@ fatal(va_alist) /* fmt, args */
|
|||
}
|
||||
#endif
|
||||
|
||||
static
|
||||
static void
|
||||
_error(class, fn, ln, fmt, ap)
|
||||
int class;
|
||||
char *fn;
|
||||
|
|
|
@ -37,6 +37,9 @@ arith NewLocal(); /* util.c */
|
|||
#define LocalPtrVar() NewLocal(pointer_size, pointer_align, reg_pointer, REGISTER)
|
||||
extern int err_occurred; /* error.c */
|
||||
|
||||
void store_val();
|
||||
void load_val();
|
||||
|
||||
/* EVAL() is the main expression-tree evaluator, which turns
|
||||
any legal expression tree into EM code. parameters.h:
|
||||
|
||||
|
@ -63,6 +66,7 @@ extern int err_occurred; /* error.c */
|
|||
labels, in case they are specified (i.e. are non-zero)
|
||||
*/
|
||||
|
||||
void
|
||||
EVAL(expr, val, code, true_label, false_label)
|
||||
register struct expr *expr;
|
||||
int val, code;
|
||||
|
@ -836,6 +840,7 @@ ptr_add(size)
|
|||
- into a local static variable
|
||||
- absolute addressing
|
||||
*/
|
||||
void
|
||||
store_val(vl, tp)
|
||||
register struct value *vl;
|
||||
register struct type *tp;
|
||||
|
@ -907,6 +912,7 @@ store_val(vl, tp)
|
|||
- static variable
|
||||
- local variable
|
||||
*/
|
||||
void
|
||||
load_val(expr, rlval)
|
||||
register struct expr *expr; /* expression containing the value */
|
||||
int rlval; /* generate either LVAL or RVAL */
|
||||
|
|
|
@ -369,6 +369,7 @@ new_oper(tp, e1, oper, e2)
|
|||
return expr;
|
||||
}
|
||||
|
||||
void
|
||||
chk_cst_expr(expp)
|
||||
struct expr **expp;
|
||||
{
|
||||
|
|
|
@ -37,6 +37,8 @@ extern char *symbol2str();
|
|||
|
||||
#include <idf_pkg.body>
|
||||
|
||||
void global_redecl();
|
||||
|
||||
struct idf *
|
||||
gen_idf()
|
||||
{
|
||||
|
@ -248,6 +250,7 @@ declare_idf(ds, dc, lvl)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
actual_declaration(sc, tp)
|
||||
int sc;
|
||||
struct type *tp;
|
||||
|
@ -269,6 +272,7 @@ actual_declaration(sc, tp)
|
|||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
global_redecl(idf, new_sc, tp)
|
||||
register struct idf *idf;
|
||||
struct type *tp;
|
||||
|
@ -393,6 +397,7 @@ declare_params(dc)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
idf_initialized(idf)
|
||||
register struct idf *idf;
|
||||
{
|
||||
|
@ -429,6 +434,7 @@ declare_enum(tp, idf, l)
|
|||
idf->id_def->df_address = l;
|
||||
}
|
||||
|
||||
void
|
||||
check_formals(idf, dc)
|
||||
struct idf *idf;
|
||||
struct declarator *dc;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "parameters.h"
|
||||
|
||||
#ifndef NOPP
|
||||
|
@ -44,7 +45,7 @@ init_pp()
|
|||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
long clock, sys_time();
|
||||
time_t clock;
|
||||
static char dbuf[30];
|
||||
static char tbuf[30];
|
||||
struct tm *tp;
|
||||
|
@ -70,7 +71,7 @@ init_pp()
|
|||
/* Initialize __LINE__, __FILE__, __DATE__, __TIME__,
|
||||
and __STDC__ macro definitions.
|
||||
*/
|
||||
clock = sys_time();
|
||||
clock = time(NULL);
|
||||
tp = localtime(&clock);
|
||||
|
||||
/* __DATE__ */
|
||||
|
|
|
@ -46,6 +46,11 @@ static int pack_level;
|
|||
struct type **gen_tphead(), **gen_tpmiddle();
|
||||
struct sdef *gen_align_to_next();
|
||||
struct e_stack *p_stack;
|
||||
|
||||
void pad();
|
||||
void gen_simple_exp();
|
||||
void gen_tpcheck();
|
||||
|
||||
}
|
||||
|
||||
/* initial_value recursively guides the initialisation expression.
|
||||
|
@ -122,6 +127,7 @@ initial_value_list(register struct type **tpp; struct expr **expp;)
|
|||
;
|
||||
|
||||
{
|
||||
void
|
||||
gen_tpcheck(tpp)
|
||||
struct type **tpp;
|
||||
{
|
||||
|
@ -147,6 +153,7 @@ gen_tpcheck(tpp)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
gen_simple_exp(tpp, expp)
|
||||
struct type **tpp;
|
||||
struct expr **expp;
|
||||
|
@ -465,6 +472,7 @@ check_and_pad(expp, tpp)
|
|||
/* pad() fills an element of type tp with zeroes.
|
||||
If the element is an aggregate, pad() is called recursively.
|
||||
*/
|
||||
void
|
||||
pad(tpx)
|
||||
struct type *tpx;
|
||||
{
|
||||
|
|
|
@ -46,6 +46,8 @@ struct sp_id special_ids[] = {
|
|||
{0, 0}
|
||||
};
|
||||
|
||||
void dependency();
|
||||
|
||||
#ifndef NOCROSS
|
||||
arith
|
||||
short_size = SZ_SHORT,
|
||||
|
@ -181,6 +183,7 @@ char *s;
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
dependency(s, source)
|
||||
char *s, *source;
|
||||
{
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
extern char options[];
|
||||
|
||||
void
|
||||
check_for_void(pl)
|
||||
register struct proto *pl;
|
||||
{
|
||||
|
@ -261,6 +262,7 @@ declare_protos(dc)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
update_proto(tp, otp)
|
||||
register struct type *tp, *otp;
|
||||
{
|
||||
|
@ -312,6 +314,7 @@ update_proto(tp, otp)
|
|||
/* struct/union and enum tags can be declared inside prototypes
|
||||
* remove them from the symbol-table
|
||||
*/
|
||||
void
|
||||
remove_proto_tag(tp)
|
||||
struct type *tp;
|
||||
{
|
||||
|
@ -380,6 +383,7 @@ remove_proto_idfs(pl)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
call_proto(expp)
|
||||
register struct expr **expp;
|
||||
{
|
||||
|
|
|
@ -26,6 +26,10 @@ extern int InputLevel;
|
|||
struct repl *ReplaceList; /* list of currently active macros */
|
||||
extern char *strcat(), *strcpy();
|
||||
|
||||
void macro2buffer();
|
||||
void getactuals();
|
||||
void expand_defined();
|
||||
|
||||
int
|
||||
replace(idf)
|
||||
register struct idf *idf;
|
||||
|
@ -172,6 +176,7 @@ expand_macro(repl, idf)
|
|||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
expand_defined(repl)
|
||||
register struct repl *repl;
|
||||
{
|
||||
|
@ -211,6 +216,7 @@ newarg(args)
|
|||
args->a_rawptr = args->a_rawbuf = Malloc(args->a_rawsize = ARGBUF);
|
||||
}
|
||||
|
||||
void
|
||||
getactuals(repl, idf)
|
||||
struct repl *repl;
|
||||
register struct idf *idf;
|
||||
|
@ -529,6 +535,7 @@ macro_func(idef)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
macro2buffer(repl, idf, args)
|
||||
register struct repl *repl;
|
||||
register struct idf *idf;
|
||||
|
|
|
@ -72,7 +72,7 @@ adds_db_str(s)
|
|||
while (*s) addc_db_str(*s++);
|
||||
}
|
||||
|
||||
static
|
||||
static void
|
||||
stb_type(tp)
|
||||
register struct type *tp;
|
||||
{
|
||||
|
|
|
@ -57,6 +57,7 @@ stack_level() {
|
|||
#endif /* LINT */
|
||||
}
|
||||
|
||||
void
|
||||
stack_idf(idf, stl)
|
||||
struct idf *idf;
|
||||
register struct stack_level *stl;
|
||||
|
|
|
@ -159,6 +159,7 @@ code_endswitch()
|
|||
unstack_stmt();
|
||||
}
|
||||
|
||||
void
|
||||
code_case(expr)
|
||||
struct expr *expr;
|
||||
{
|
||||
|
@ -227,6 +228,7 @@ code_case(expr)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
code_default()
|
||||
{
|
||||
register struct switch_hdr *sh = switch_stack;
|
||||
|
|
|
@ -163,6 +163,7 @@ LocalFinish()
|
|||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
RegisterAccount(offset, size, regtype, sc)
|
||||
arith offset, size;
|
||||
{
|
||||
|
|
|
@ -35,6 +35,8 @@ extern arith char_constant();
|
|||
#define FLG_ESEEN 0x01 /* possibly a floating point number */
|
||||
#define FLG_DOTSEEN 0x02 /* certainly a floating point number */
|
||||
|
||||
void skipcomment();
|
||||
|
||||
int
|
||||
LLlex()
|
||||
{
|
||||
|
@ -325,6 +327,7 @@ garbage:
|
|||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
void
|
||||
skipcomment()
|
||||
{
|
||||
/* The last character read has been the '*' of '/_*'. The
|
||||
|
|
|
@ -32,6 +32,9 @@ int svnestlevel[30] = {-1};
|
|||
int nestcount;
|
||||
extern int do_preprocess;
|
||||
|
||||
void macro_def();
|
||||
void do_define();
|
||||
|
||||
char *
|
||||
GetIdentifier(skiponerr)
|
||||
int skiponerr; /* skip the rest of the line on error */
|
||||
|
@ -148,6 +151,7 @@ domacro()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
skip_block(to_endif)
|
||||
int to_endif;
|
||||
{
|
||||
|
@ -327,6 +331,7 @@ do_include()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
do_define()
|
||||
{
|
||||
/* do_define() interprets a #define control line.
|
||||
|
@ -566,6 +571,7 @@ getparams(buf, parbuf)
|
|||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
void
|
||||
macro_def(id, text, nformals, length, flags)
|
||||
register struct idf *id;
|
||||
char *text;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "system.h"
|
||||
#include "alloc.h"
|
||||
#include "time.h"
|
||||
|
@ -42,7 +43,7 @@ init_pp()
|
|||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
long clock, sys_time();
|
||||
time_t clock;
|
||||
static char dbuf[30];
|
||||
static char tbuf[30];
|
||||
struct tm *tp;
|
||||
|
@ -68,7 +69,7 @@ init_pp()
|
|||
/* Initialize __LINE__, __FILE__, __DATE__, __TIME__,
|
||||
and __STDC__ macro definitions.
|
||||
*/
|
||||
clock = sys_time();
|
||||
clock = time(NULL);
|
||||
tp = localtime(&clock);
|
||||
|
||||
/* __DATE__ */
|
||||
|
|
|
@ -32,6 +32,8 @@ char *prog_name;
|
|||
extern char **inctable;
|
||||
extern int inc_max, inc_total;
|
||||
|
||||
void dependency();
|
||||
|
||||
main(argc, argv)
|
||||
char *argv[];
|
||||
{
|
||||
|
@ -140,6 +142,7 @@ add_dependency(s)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
dependency(s, source)
|
||||
char *s, *source;
|
||||
{
|
||||
|
|
|
@ -102,6 +102,7 @@ do_pragma()
|
|||
|
||||
char Xbuf[256];
|
||||
|
||||
void
|
||||
preprocess(fn)
|
||||
char *fn;
|
||||
{
|
||||
|
|
|
@ -26,6 +26,10 @@ extern char *strcat();
|
|||
extern int InputLevel;
|
||||
struct repl *ReplaceList; /* list of currently active macros */
|
||||
|
||||
void expand_defined();
|
||||
void getactuals();
|
||||
void macro2buffer();
|
||||
|
||||
int
|
||||
replace(idf)
|
||||
register struct idf *idf;
|
||||
|
@ -165,6 +169,7 @@ expand_macro(repl, idf)
|
|||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
expand_defined(repl)
|
||||
register struct repl *repl;
|
||||
{
|
||||
|
@ -208,6 +213,7 @@ newarg(args)
|
|||
args->a_rawptr = args->a_rawbuf = Malloc((unsigned)(args->a_rawsize = ARGBUF));
|
||||
}
|
||||
|
||||
void
|
||||
getactuals(repl, idf)
|
||||
struct repl *repl;
|
||||
register struct idf *idf;
|
||||
|
@ -522,6 +528,7 @@ macro_func(idef)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
macro2buffer(repl, idf, args)
|
||||
register struct repl *repl;
|
||||
register struct idf *idf;
|
||||
|
|
23
lang/cem/libcc.ansi/malloc/calloc.c
Normal file
23
lang/cem/libcc.ansi/malloc/calloc.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void* calloc(size_t nmemb, size_t size)
|
||||
{
|
||||
size_t bytes = nmemb * size;
|
||||
void* ptr;
|
||||
|
||||
/* Test for overflow.
|
||||
* See http://stackoverflow.com/questions/1815367/multiplication-of-large-numbers-how-to-catch-overflow
|
||||
*/
|
||||
|
||||
if ((nmemb == 0) || (size == 0) || (nmemb > (SIZE_MAX / size)))
|
||||
return NULL;
|
||||
|
||||
ptr = malloc(bytes);
|
||||
if (!ptr)
|
||||
return NULL;
|
||||
|
||||
memset(ptr, 0, bytes);
|
||||
return ptr;
|
||||
}
|
|
@ -180,6 +180,7 @@ getch()
|
|||
return ch;
|
||||
}
|
||||
|
||||
void
|
||||
CheckForLineDirective()
|
||||
{
|
||||
register int ch = getch();
|
||||
|
|
|
@ -54,6 +54,9 @@ struct case_entry {
|
|||
arith ce_low, ce_up; /* lower and upper bound of range */
|
||||
};
|
||||
|
||||
void AddCases();
|
||||
void AddOneCase();
|
||||
|
||||
/* STATICALLOCDEF "case_entry" 20 */
|
||||
|
||||
/* The constant DENSITY determines when CSA and when CSB instructions
|
||||
|
@ -237,6 +240,7 @@ FreeSh(sh)
|
|||
free_switch_hdr(sh);
|
||||
}
|
||||
|
||||
void
|
||||
AddCases(sh, node, lbl)
|
||||
struct switch_hdr *sh;
|
||||
register t_node *node;
|
||||
|
@ -264,6 +268,7 @@ AddCases(sh, node, lbl)
|
|||
AddOneCase(sh, node, node, lbl);
|
||||
}
|
||||
|
||||
void
|
||||
AddOneCase(sh, lnode, rnode, lbl)
|
||||
register struct switch_hdr *sh;
|
||||
t_node *lnode, *rnode;
|
||||
|
|
|
@ -53,6 +53,7 @@ df_error(nd, mess, edf)
|
|||
else node_error(nd, mess);
|
||||
}
|
||||
|
||||
void
|
||||
MkCoercion(pnd, tp)
|
||||
t_node **pnd;
|
||||
register t_type *tp;
|
||||
|
|
|
@ -37,6 +37,10 @@ extern char options[];
|
|||
extern t_desig null_desig;
|
||||
int fp_used;
|
||||
|
||||
void RangeCheck();
|
||||
void CodeParameters();
|
||||
void CodeCall();
|
||||
|
||||
CodeConst(cst, size)
|
||||
arith cst;
|
||||
int size;
|
||||
|
@ -55,6 +59,7 @@ CodeConst(cst, size)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
CodeString(nd)
|
||||
register t_node *nd;
|
||||
{
|
||||
|
@ -288,6 +293,7 @@ CodeCoercion(t1, t2)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
CodeCall(nd)
|
||||
register t_node *nd;
|
||||
{
|
||||
|
@ -355,6 +361,7 @@ CodeCall(nd)
|
|||
DoLineno(nd);
|
||||
}
|
||||
|
||||
void
|
||||
CodeParameters(param, arg)
|
||||
t_param *param;
|
||||
register t_node *arg;
|
||||
|
@ -672,6 +679,7 @@ needs_rangecheck(tpl, tpr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
RangeCheck(tpl, tpr)
|
||||
register t_type *tpl, *tpr;
|
||||
{
|
||||
|
|
|
@ -45,6 +45,8 @@ arith min_int[] = { 0L, -128L, -32768L, 0L, -2147483647L-1 };
|
|||
|
||||
extern char options[];
|
||||
|
||||
void CutSize();
|
||||
|
||||
overflow(expp)
|
||||
t_node *expp;
|
||||
{
|
||||
|
@ -160,6 +162,7 @@ divide(pdiv, prem)
|
|||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
cstibin(expp)
|
||||
t_node **expp;
|
||||
{
|
||||
|
@ -351,6 +354,7 @@ cstfbin(expp)
|
|||
CutSize(exp);
|
||||
}
|
||||
|
||||
void
|
||||
cstubin(expp)
|
||||
t_node **expp;
|
||||
{
|
||||
|
@ -457,6 +461,7 @@ cstubin(expp)
|
|||
CutSize(exp);
|
||||
}
|
||||
|
||||
void
|
||||
cstset(expp)
|
||||
t_node **expp;
|
||||
{
|
||||
|
@ -648,6 +653,7 @@ cstcall(expp, call)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
CutSize(expr)
|
||||
register t_node *expr;
|
||||
{
|
||||
|
|
|
@ -533,6 +533,7 @@ CodeFieldDesig(df, ds)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
CodeVarDesig(df, ds)
|
||||
register t_def *df;
|
||||
register t_desig *ds;
|
||||
|
|
|
@ -247,6 +247,7 @@ EnterParamList(ppr, Idlist, type, VARp, off)
|
|||
|
||||
STATIC t_def *DoImport();
|
||||
|
||||
void
|
||||
ImportEffects(idef, scope, flag)
|
||||
register t_def *idef;
|
||||
t_scope *scope;
|
||||
|
@ -481,6 +482,7 @@ CheckForImports(df)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
EnterFromImportList(idlist, FromDef, FromId)
|
||||
register t_node *idlist;
|
||||
register t_def *FromDef;
|
||||
|
|
|
@ -61,6 +61,8 @@ extern char *symbol2str();
|
|||
node, whereas other errors use the information in the token.
|
||||
*/
|
||||
|
||||
void _error();
|
||||
|
||||
#if __STDC__
|
||||
#ifdef DEBUG
|
||||
/*VARARGS*/
|
||||
|
@ -318,6 +320,7 @@ crash(va_alist)
|
|||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
_error(class, node, fmt, ap, warn_class)
|
||||
int class;
|
||||
t_node *node;
|
||||
|
|
|
@ -81,6 +81,7 @@ dot2leaf(class)
|
|||
return nd;
|
||||
}
|
||||
|
||||
void
|
||||
FreeNode(nd)
|
||||
register t_node *nd;
|
||||
{
|
||||
|
|
|
@ -71,7 +71,7 @@ adds_db_str(s)
|
|||
while (*s) addc_db_str(*s++);
|
||||
}
|
||||
|
||||
static
|
||||
static void
|
||||
stb_type(tp, assign_num)
|
||||
register t_type *tp;
|
||||
{
|
||||
|
|
|
@ -74,6 +74,8 @@ t_type
|
|||
*std_type,
|
||||
*error_type;
|
||||
|
||||
void ArraySizes();
|
||||
|
||||
t_type *
|
||||
construct_type(fund, tp)
|
||||
int fund;
|
||||
|
@ -576,6 +578,7 @@ ArrayElSize(tp)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ArraySizes(tp)
|
||||
register t_type *tp;
|
||||
{
|
||||
|
|
|
@ -64,7 +64,7 @@ static int WalkDef();
|
|||
static int stabdef();
|
||||
#endif
|
||||
static int MkCalls();
|
||||
static int UseWarnings();
|
||||
static void UseWarnings();
|
||||
|
||||
#define NO_EXIT_LABEL ((label) 0)
|
||||
#define RETURN_LABEL ((label) 1)
|
||||
|
@ -72,6 +72,8 @@ static int UseWarnings();
|
|||
#define REACH_FLAG 1
|
||||
#define EXIT_FLAG 2
|
||||
|
||||
void DoAssign();
|
||||
|
||||
int
|
||||
LblWalkNode(lbl, nd, exit, reach)
|
||||
label lbl, exit;
|
||||
|
@ -995,6 +997,7 @@ node_warning(nd, W_OLDFASHIONED, "compatibility required in FOR statement");
|
|||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
DoAssign(nd)
|
||||
register t_node *nd;
|
||||
{
|
||||
|
@ -1057,7 +1060,7 @@ RegisterMessage(df)
|
|||
}
|
||||
}
|
||||
|
||||
static
|
||||
static void
|
||||
df_warning(nd, df, warning)
|
||||
t_node *nd;
|
||||
t_def *df;
|
||||
|
@ -1080,7 +1083,7 @@ df_warning(nd, df, warning)
|
|||
}
|
||||
}
|
||||
|
||||
static
|
||||
static void
|
||||
UseWarnings(df)
|
||||
register t_def *df;
|
||||
{
|
||||
|
|
|
@ -120,7 +120,7 @@ CommentOptions()
|
|||
}
|
||||
|
||||
|
||||
STATIC
|
||||
STATIC void
|
||||
SkipComment()
|
||||
{
|
||||
/* Skip ISO-Pascal comments (* ... *) or { ... }.
|
||||
|
@ -216,6 +216,7 @@ register int delim;
|
|||
|
||||
static char *s_error = "illegal line directive";
|
||||
|
||||
void
|
||||
CheckForLineDirective()
|
||||
{
|
||||
register int ch;
|
||||
|
|
|
@ -47,6 +47,7 @@ MarkDef(nd, flags, on)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
AssertStat(expp, line)
|
||||
register struct node *expp;
|
||||
unsigned short line;
|
||||
|
@ -69,6 +70,7 @@ AssertStat(expp, line)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
AssignStat(left, right)
|
||||
register struct node *left, *right;
|
||||
{
|
||||
|
@ -131,6 +133,7 @@ AssignStat(left, right)
|
|||
FreeNode(right);
|
||||
}
|
||||
|
||||
void
|
||||
ProcStat(nd)
|
||||
register struct node *nd;
|
||||
{
|
||||
|
@ -142,6 +145,7 @@ ProcStat(nd)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ChkForStat(nd)
|
||||
register struct node *nd;
|
||||
{
|
||||
|
@ -202,6 +206,7 @@ ChkForStat(nd)
|
|||
return;
|
||||
}
|
||||
|
||||
void
|
||||
EndForStat(nd)
|
||||
register struct node *nd;
|
||||
{
|
||||
|
@ -283,6 +288,7 @@ CodeEndFor(nd, stepsize, l1, l2, tmp2)
|
|||
C_asp(int_size);
|
||||
}
|
||||
|
||||
void
|
||||
WithStat(nd)
|
||||
struct node *nd;
|
||||
{
|
||||
|
|
|
@ -40,6 +40,7 @@ struct case_entry {
|
|||
*/
|
||||
#define compact(nr, low, up) (nr != 0 && (up - low) / nr <= DENSITY)
|
||||
|
||||
void
|
||||
CaseExpr(nd)
|
||||
struct node *nd;
|
||||
{
|
||||
|
@ -62,6 +63,7 @@ CaseExpr(nd)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
CaseEnd(nd, exit_label)
|
||||
struct node *nd;
|
||||
label exit_label;
|
||||
|
|
|
@ -1183,13 +1183,6 @@ ChkStandard(expp,left)
|
|||
expp->nd_type = NULLTYPE;
|
||||
break;
|
||||
|
||||
case R_MARK:
|
||||
case R_RELEASE:
|
||||
if( !(left = getarg(&arg, T_POINTER, 1, name, NULLTYPE)) )
|
||||
return 0;
|
||||
expp->nd_type = NULLTYPE;
|
||||
break;
|
||||
|
||||
case R_HALT:
|
||||
if( !arg->nd_right ) /* insert 0 parameter */
|
||||
arg->nd_right = ZeroParam();
|
||||
|
|
|
@ -24,6 +24,11 @@
|
|||
|
||||
int fp_used;
|
||||
|
||||
void Long2Int();
|
||||
void Int2Long();
|
||||
void genrck();
|
||||
void CodeCall();
|
||||
|
||||
CodeFil()
|
||||
{
|
||||
if ( !options['L'] )
|
||||
|
@ -791,6 +796,7 @@ CodePString(nd, tp)
|
|||
C_loi(tp->tp_size);
|
||||
}
|
||||
|
||||
void
|
||||
CodeCall(nd)
|
||||
register struct node *nd;
|
||||
{
|
||||
|
@ -1070,16 +1076,6 @@ CodeStd(nd)
|
|||
C_asp(pointer_size + word_size);
|
||||
break;
|
||||
|
||||
case R_MARK:
|
||||
case R_RELEASE:
|
||||
CodeDAddress(left);
|
||||
if( req == R_MARK )
|
||||
C_cal("_sav");
|
||||
else
|
||||
C_cal("_rst");
|
||||
C_asp(pointer_size);
|
||||
break;
|
||||
|
||||
case R_HALT:
|
||||
if( left )
|
||||
CodePExpr(left);
|
||||
|
@ -1095,6 +1091,7 @@ CodeStd(nd)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Long2Int()
|
||||
{
|
||||
/* convert a long to integer */
|
||||
|
@ -1106,6 +1103,7 @@ Long2Int()
|
|||
C_cii();
|
||||
}
|
||||
|
||||
void
|
||||
Int2Long()
|
||||
{
|
||||
/* convert integer to long */
|
||||
|
@ -1160,6 +1158,7 @@ RangeCheck(tpl, tpr)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
genrck(tp)
|
||||
register struct type *tp;
|
||||
{
|
||||
|
|
|
@ -66,6 +66,7 @@ cstunary(expp)
|
|||
expp->nd_right = NULLNODE;
|
||||
}
|
||||
|
||||
void
|
||||
cstbin(expp)
|
||||
register struct node *expp;
|
||||
{
|
||||
|
@ -195,6 +196,7 @@ cstbin(expp)
|
|||
expp->nd_left = expp->nd_right = NULLNODE;
|
||||
}
|
||||
|
||||
void
|
||||
cstset(expp)
|
||||
register struct node *expp;
|
||||
{
|
||||
|
|
|
@ -116,6 +116,7 @@ define(id, scope, kind)
|
|||
return MkDef(id, scope, kind);
|
||||
}
|
||||
|
||||
void
|
||||
DoDirective(directive, nd, tp, scl, function)
|
||||
struct idf *directive;
|
||||
struct node *nd;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
struct desig InitDesig = {DSG_INIT, 0, 0, NULLDEF, 0};
|
||||
struct withdesig *WithDesigs;
|
||||
|
||||
void CodeValue();
|
||||
|
||||
STATIC int
|
||||
properly(ds, size, al)
|
||||
|
@ -71,6 +72,7 @@ CodeCopy(lhs, rhs, sz, psize)
|
|||
C_sti(sz);
|
||||
}
|
||||
|
||||
void
|
||||
CodeMove(rhs, left, rtp)
|
||||
register struct desig *rhs;
|
||||
register struct node *left;
|
||||
|
@ -150,6 +152,7 @@ CodeMove(rhs, left, rtp)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
CodeValue(ds, tp)
|
||||
register struct desig *ds;
|
||||
register struct type *tp;
|
||||
|
@ -366,6 +369,7 @@ CodeFieldDesig(df, ds)
|
|||
ds->dsg_packed = df->fld_flags & F_PACKED;
|
||||
}
|
||||
|
||||
void
|
||||
CodeVarDesig(df, ds)
|
||||
register struct def *df;
|
||||
register struct desig *ds;
|
||||
|
|
|
@ -39,6 +39,8 @@ int err_occurred;
|
|||
|
||||
extern char *symbol2str();
|
||||
|
||||
void _error();
|
||||
|
||||
/* There are three general error-message functions:
|
||||
lexerror() lexical and pre-processor error messages
|
||||
error() syntactic and pre-processor messagese
|
||||
|
@ -304,6 +306,7 @@ crash(va_alist)
|
|||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
_error(class, node, fmt, ap)
|
||||
int class;
|
||||
struct node *node;
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include "scope.h"
|
||||
#include "type.h"
|
||||
|
||||
void CodeLabel();
|
||||
|
||||
|
||||
DeclLabel(nd)
|
||||
struct node *nd;
|
||||
|
@ -103,6 +105,7 @@ TstLabel(nd, Slevel)
|
|||
CodeLabel(df, 1);
|
||||
}
|
||||
|
||||
void
|
||||
DefLabel(nd, Slevel)
|
||||
register struct node *nd;
|
||||
{
|
||||
|
@ -139,6 +142,7 @@ DefLabel(nd, Slevel)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
CodeLabel(df, local)
|
||||
register struct def *df;
|
||||
{
|
||||
|
|
|
@ -189,10 +189,6 @@ AddRequired()
|
|||
/* DYNAMIC ALLOCATION PROCEDURES */
|
||||
(void) Enter("new", D_PROCEDURE, std_type, R_NEW);
|
||||
(void) Enter("dispose", D_PROCEDURE, std_type, R_DISPOSE);
|
||||
if( !options['s'] ) {
|
||||
(void) Enter("mark", D_PROCEDURE, std_type, R_MARK);
|
||||
(void) Enter("release", D_PROCEDURE, std_type, R_RELEASE);
|
||||
}
|
||||
|
||||
/* MISCELLANEOUS PROCEDURE(S) */
|
||||
if( !options['s'] )
|
||||
|
|
|
@ -42,6 +42,7 @@ MkLeaf(class, token)
|
|||
return nd;
|
||||
}
|
||||
|
||||
void
|
||||
FreeNode(nd)
|
||||
register struct node *nd;
|
||||
{
|
||||
|
|
|
@ -15,6 +15,8 @@ static int inpflag = 0; /* input mentioned in heading ? */
|
|||
static int outpflag = 0; /* output mentioned in heading ? */
|
||||
static label extfl_label; /* label of array of file pointers */
|
||||
|
||||
void make_extfl_args();
|
||||
|
||||
set_inp()
|
||||
{
|
||||
inpflag = 1;
|
||||
|
@ -25,6 +27,7 @@ set_outp()
|
|||
outpflag = 1;
|
||||
}
|
||||
|
||||
void
|
||||
make_extfl()
|
||||
{
|
||||
if( err_occurred ) return;
|
||||
|
@ -54,6 +57,7 @@ make_extfl()
|
|||
make_extfl_args( GlobalScope->sc_def );
|
||||
}
|
||||
|
||||
void
|
||||
make_extfl_args(df)
|
||||
register struct def *df;
|
||||
{
|
||||
|
|
|
@ -19,6 +19,12 @@
|
|||
|
||||
extern char *sprint();
|
||||
|
||||
void CodeRead();
|
||||
void CodeReadln();
|
||||
void CodeWrite();
|
||||
void CodeWriteln();
|
||||
|
||||
void
|
||||
ChkRead(arg)
|
||||
register struct node *arg;
|
||||
{
|
||||
|
@ -86,6 +92,7 @@ ChkRead(arg)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ChkReadln(arg)
|
||||
register struct node *arg;
|
||||
{
|
||||
|
@ -142,6 +149,7 @@ ChkReadln(arg)
|
|||
CodeReadln(file);
|
||||
}
|
||||
|
||||
void
|
||||
ChkWrite(arg)
|
||||
register struct node *arg;
|
||||
{
|
||||
|
@ -183,6 +191,7 @@ ChkWrite(arg)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ChkWriteln(arg)
|
||||
register struct node *arg;
|
||||
{
|
||||
|
@ -318,6 +327,7 @@ ChkStdInOut(name, st_out)
|
|||
return nd;
|
||||
}
|
||||
|
||||
void
|
||||
CodeRead(file, arg)
|
||||
register struct node *file, *arg;
|
||||
{
|
||||
|
@ -376,6 +386,7 @@ CodeRead(file, arg)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
CodeReadln(file)
|
||||
struct node *file;
|
||||
{
|
||||
|
@ -386,6 +397,7 @@ CodeReadln(file)
|
|||
C_asp(pointer_size);
|
||||
}
|
||||
|
||||
void
|
||||
CodeWrite(file, arg)
|
||||
register struct node *file, *arg;
|
||||
{
|
||||
|
@ -472,6 +484,7 @@ CodeWrite(file, arg)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
CodeWriteln(file)
|
||||
register struct node *file;
|
||||
{
|
||||
|
|
|
@ -1,48 +1,51 @@
|
|||
/* REQUIRED PROCEDURES AND FUNCTIONS */
|
||||
|
||||
/* PROCEDURES */
|
||||
/* FILE HANDLING */
|
||||
#define R_REWRITE 1
|
||||
#define R_PUT 2
|
||||
#define R_RESET 3
|
||||
#define R_GET 4
|
||||
#define R_PAGE 5
|
||||
enum
|
||||
{
|
||||
R__UNUSED = 0,
|
||||
|
||||
/* DYNAMIC ALLOCATION */
|
||||
#define R_NEW 6
|
||||
#define R_DISPOSE 7
|
||||
#define R_MARK 8
|
||||
#define R_RELEASE 9
|
||||
/* PROCEDURES */
|
||||
/* FILE HANDLING */
|
||||
R_REWRITE,
|
||||
R_PUT,
|
||||
R_RESET,
|
||||
R_GET,
|
||||
R_PAGE,
|
||||
|
||||
/* MISCELLANEOUS PROCEDURE(S) */
|
||||
#define R_HALT 10
|
||||
/* DYNAMIC ALLOCATION */
|
||||
R_NEW,
|
||||
R_DISPOSE,
|
||||
|
||||
/* TRANSFER */
|
||||
#define R_PACK 11
|
||||
#define R_UNPACK 12
|
||||
/* MISCELLANEOUS PROCEDURE(S) */
|
||||
R_HALT,
|
||||
|
||||
/* FUNCTIONS */
|
||||
/* ARITHMETIC */
|
||||
#define R_ABS 13
|
||||
#define R_SQR 14
|
||||
#define R_SIN 15
|
||||
#define R_COS 16
|
||||
#define R_EXP 17
|
||||
#define R_LN 18
|
||||
#define R_SQRT 19
|
||||
#define R_ARCTAN 20
|
||||
/* TRANSFER */
|
||||
R_PACK,
|
||||
R_UNPACK,
|
||||
|
||||
/* TRANSFER */
|
||||
#define R_TRUNC 21
|
||||
#define R_ROUND 22
|
||||
/* FUNCTIONS */
|
||||
/* ARITHMETIC */
|
||||
R_ABS,
|
||||
R_SQR,
|
||||
R_SIN,
|
||||
R_COS,
|
||||
R_EXP,
|
||||
R_LN,
|
||||
R_SQRT,
|
||||
R_ARCTAN,
|
||||
|
||||
/* ORDINAL */
|
||||
#define R_ORD 23
|
||||
#define R_CHR 24
|
||||
#define R_SUCC 25
|
||||
#define R_PRED 26
|
||||
/* TRANSFER */
|
||||
R_TRUNC,
|
||||
R_ROUND,
|
||||
|
||||
/* BOOLEAN */
|
||||
#define R_ODD 27
|
||||
#define R_EOF 28
|
||||
#define R_EOLN 29
|
||||
/* ORDINAL */
|
||||
R_ORD,
|
||||
R_CHR,
|
||||
R_SUCC,
|
||||
R_PRED,
|
||||
|
||||
/* BOOLEAN */
|
||||
R_ODD,
|
||||
R_EOF,
|
||||
R_EOLN,
|
||||
};
|
||||
|
|
|
@ -71,7 +71,7 @@ adds_db_str(s)
|
|||
while (*s) addc_db_str(*s++);
|
||||
}
|
||||
|
||||
static
|
||||
static void
|
||||
stb_type(tp, assign_num)
|
||||
register struct type *tp;
|
||||
{
|
||||
|
@ -247,6 +247,7 @@ stb_addtp(s, tp)
|
|||
(arith) 0);
|
||||
}
|
||||
|
||||
void
|
||||
stb_string(df, kind)
|
||||
register struct def *df;
|
||||
long kind;
|
||||
|
|
|
@ -51,6 +51,8 @@ struct type
|
|||
*void_type,
|
||||
*error_type;
|
||||
|
||||
void ArraySizes();
|
||||
|
||||
CheckTypeSizes()
|
||||
{
|
||||
/* first, do some checking
|
||||
|
@ -442,6 +444,7 @@ ArrayElSize(tp, packed)
|
|||
return algn;
|
||||
}
|
||||
|
||||
void
|
||||
ArraySizes(tp)
|
||||
register struct type *tp;
|
||||
{
|
||||
|
@ -489,6 +492,7 @@ ArraySizes(tp)
|
|||
C_rom_cst(tp->arr_elsize);
|
||||
}
|
||||
|
||||
void
|
||||
FreeForward(for_type)
|
||||
register struct forwtype *for_type;
|
||||
{
|
||||
|
|
|
@ -11,7 +11,6 @@ for _, plat in ipairs(vars.plats) do
|
|||
"./fif.e",
|
||||
"./gto.e",
|
||||
"./hol0.e",
|
||||
"./sav.e",
|
||||
"./sig.e",
|
||||
"./trap.e",
|
||||
"./trp.e",
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
/*
|
||||
* File: - dis.c
|
||||
*
|
||||
* dispose() built in standard procedure in Pascal (6.6.5.3)
|
||||
*
|
||||
* Re-implementation of storage allocator for Ack Pascal compiler
|
||||
* under Linux, and other UNIX-like systems.
|
||||
*
|
||||
* Written by Erik Backerud, 2010-10-01
|
||||
*
|
||||
* Original copyright and author info below:
|
||||
*/
|
||||
/* $Id$ */
|
||||
/*
|
||||
* (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
*
|
||||
* This product is part of the Amsterdam Compiler Kit.
|
||||
*
|
||||
* Permission to use, sell, duplicate or disclose this software must be
|
||||
* obtained in writing. Requests for such permissions may be sent to
|
||||
*
|
||||
* Dr. Andrew S. Tanenbaum
|
||||
* Wiskundig Seminarium
|
||||
* Vrije Universiteit
|
||||
* Postbox 7161
|
||||
* 1007 MC Amsterdam
|
||||
* The Netherlands
|
||||
*
|
||||
*/
|
||||
|
||||
/* Author: J.W. Stevenson */
|
||||
|
||||
#include <pc_err.h>
|
||||
|
||||
#define assert() /* nothing */
|
||||
|
||||
/*
|
||||
* use a singly linked list of free blocks.
|
||||
*/
|
||||
struct adm {
|
||||
struct adm *next;
|
||||
int size;
|
||||
};
|
||||
|
||||
struct adm *freep = 0; /* first element on free list */
|
||||
|
||||
extern void _trp(int);
|
||||
|
||||
/*
|
||||
* Dispose
|
||||
* Called with two arguments:
|
||||
* n the size of the block to be freed, in bytes,
|
||||
* pp address of pointer to data.
|
||||
*/
|
||||
void
|
||||
_dis(int n, struct adm **pp)
|
||||
{
|
||||
struct adm *block; /* the block of data being freed (inc. header) */
|
||||
struct adm *p, *q;
|
||||
|
||||
if (*pp == 0) {
|
||||
_trp(EFREE);
|
||||
}
|
||||
block = *pp - 1;
|
||||
if (freep == 0) {
|
||||
freep = block;
|
||||
block->next = 0;
|
||||
} else {
|
||||
q = 0; /* trail one behind */
|
||||
for (p = freep; p < block; p = p->next) {
|
||||
if (p == 0) { /* We reached the end of the free list. */
|
||||
break;
|
||||
}
|
||||
q = p;
|
||||
/* check if block is contained in the free block p */
|
||||
if (p+p->size > block) {
|
||||
_trp(EFREE);
|
||||
}
|
||||
}
|
||||
if (p == block) { /* this block already freed */
|
||||
_trp(EFREE);
|
||||
}
|
||||
if (q == 0) { /* block is first */
|
||||
freep = block;
|
||||
block->next = p;
|
||||
} else {
|
||||
q->next = block;
|
||||
}
|
||||
block->next = p;
|
||||
/* merge with successor on free list? */
|
||||
if (block + block->size == p) {
|
||||
block->size = block->size + p->size;
|
||||
block->next = p->next;
|
||||
}
|
||||
/* merge with preceding block on free list? */
|
||||
if (q != 0 && q+q->size == block) {
|
||||
q->size = q->size + block->size;
|
||||
q->next = block->next;
|
||||
}
|
||||
}
|
||||
} /* _dis */
|
|
@ -1,120 +1,20 @@
|
|||
/*
|
||||
* File: - new.c
|
||||
*
|
||||
* new() built in standard procedure in Pascal (6.6.5.3)
|
||||
*
|
||||
* Re-implementation of storage allocator for Ack Pascal compiler
|
||||
* under Linux, and other UNIX-like systems.
|
||||
*
|
||||
* Written by Erik Backerud, 2010-10-01
|
||||
*
|
||||
* Original copyright and author info below:
|
||||
*/
|
||||
/* $Id$ */
|
||||
/*
|
||||
* (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
*
|
||||
* This product is part of the Amsterdam Compiler Kit.
|
||||
*
|
||||
* Permission to use, sell, duplicate or disclose this software must be
|
||||
* obtained in writing. Requests for such permissions may be sent to
|
||||
*
|
||||
* Dr. Andrew S. Tanenbaum
|
||||
* Wiskundig Seminarium
|
||||
* Vrije Universiteit
|
||||
* Postbox 7161
|
||||
* 1007 MC Amsterdam
|
||||
* The Netherlands
|
||||
*
|
||||
*/
|
||||
|
||||
/* Author: J.W. Stevenson */
|
||||
#include <stdlib.h>
|
||||
#include <em_abs.h>
|
||||
#include <pc_err.h>
|
||||
|
||||
#define assert(x) /* nothing */
|
||||
#define UNDEF 0x8000
|
||||
#define NALLOC (1024) /* request this many units from OS */
|
||||
|
||||
|
||||
/*
|
||||
* use a singly linked list of free blocks.
|
||||
*/
|
||||
struct adm {
|
||||
struct adm *next;
|
||||
int size;
|
||||
};
|
||||
|
||||
extern struct adm *freep;
|
||||
|
||||
extern void _trp(int); /* called on error */
|
||||
|
||||
extern void _dis(int, struct adm **);
|
||||
|
||||
|
||||
/*
|
||||
* Helper function to request 'nu' units of memory from the OS.
|
||||
* A storage unit is sizeof(struct adm). Typically 8 bytes
|
||||
* on a 32-bit machine like i386 etc.
|
||||
*/
|
||||
static struct adm *
|
||||
morecore(unsigned nu)
|
||||
void _new(int n, void** ptr)
|
||||
{
|
||||
char *cp, *sbrk(int);
|
||||
struct adm *up;
|
||||
|
||||
if (nu < NALLOC)
|
||||
nu = NALLOC;
|
||||
cp = sbrk(nu * sizeof(struct adm));
|
||||
if (cp == (char *) -1) /* no space at all */
|
||||
return 0;
|
||||
up = (struct adm*) cp;
|
||||
up->size = nu;
|
||||
up = up + 1;
|
||||
_dis((nu - 1) * sizeof(struct adm), &up);
|
||||
return freep;
|
||||
} /* morecore */
|
||||
|
||||
/*
|
||||
* Dispose
|
||||
* Called with two arguments:
|
||||
* n the size of the block to be freed, in bytes,
|
||||
* pp address of pointer to data.
|
||||
*/
|
||||
void
|
||||
_new(int n, struct adm **pp)
|
||||
{
|
||||
int nunits; /* the unit of storage is sizeof(struct adm) */
|
||||
struct adm *p,*q;
|
||||
|
||||
/* round up size of request */
|
||||
nunits = (n + sizeof(struct adm) - 1) / sizeof(struct adm) + 1;
|
||||
|
||||
q = 0;
|
||||
for (p = freep; ; p = p->next) {
|
||||
if (p == 0) {
|
||||
p = morecore(nunits);
|
||||
if (p == 0)
|
||||
void* p = malloc(n);
|
||||
if (!p)
|
||||
_trp(EHEAP);
|
||||
q = 0;
|
||||
}
|
||||
if (p->size >= nunits) {
|
||||
if (p->size == nunits) { /* exact fit */
|
||||
if (q == 0) { /* first element on free list. */
|
||||
freep = p->next;
|
||||
} else {
|
||||
q->next = p->next;
|
||||
}
|
||||
} else { /* allocate tail end */
|
||||
q = p;
|
||||
q->size = q->size - nunits;
|
||||
p = q + q->size;
|
||||
p->next = 0;
|
||||
p->size = nunits;
|
||||
}
|
||||
break;
|
||||
}
|
||||
q = p;
|
||||
}
|
||||
*pp = p + 1;
|
||||
} /* _new */
|
||||
|
||||
*ptr = p;
|
||||
}
|
||||
|
||||
void _dis(int n, void** ptr)
|
||||
{
|
||||
free(*ptr);
|
||||
*ptr = NULL;
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
#
|
||||
; $Id$
|
||||
; (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
;
|
||||
; This product is part of the Amsterdam Compiler Kit.
|
||||
;
|
||||
; Permission to use, sell, duplicate or disclose this software must be
|
||||
; obtained in writing. Requests for such permissions may be sent to
|
||||
;
|
||||
; Dr. Andrew S. Tanenbaum
|
||||
; Wiskundig Seminarium
|
||||
; Vrije Universiteit
|
||||
; Postbox 7161
|
||||
; 1007 MC Amsterdam
|
||||
; The Netherlands
|
||||
;
|
||||
|
||||
/* Author: J.W. Stevenson */
|
||||
|
||||
|
||||
mes 2,EM_WSIZE,EM_PSIZE
|
||||
|
||||
#define PTRAD 0
|
||||
|
||||
#define HP 2
|
||||
|
||||
; _sav called with one parameter:
|
||||
; - address of pointer variable (PTRAD)
|
||||
|
||||
exp $_sav
|
||||
pro $_sav,0
|
||||
lor HP
|
||||
lal PTRAD
|
||||
loi EM_PSIZE
|
||||
sti EM_PSIZE
|
||||
ret 0
|
||||
end ?
|
||||
|
||||
; _rst is called with one parameter:
|
||||
; - address of pointer variable (PTRAD)
|
||||
|
||||
exp $_rst
|
||||
pro $_rst,0
|
||||
lal PTRAD
|
||||
loi EM_PSIZE
|
||||
loi EM_PSIZE
|
||||
str HP
|
||||
ret 0
|
||||
end ?
|
|
@ -38,6 +38,7 @@ ea_1_16(param)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ea_1(param) {
|
||||
if (! address_long) {
|
||||
ea_1_16(param);
|
||||
|
@ -134,6 +135,7 @@ regsize(sz)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
indexed() {
|
||||
if (address_long) {
|
||||
mod_2 = 0;
|
||||
|
|
|
@ -61,6 +61,7 @@ string holstr(n) word n; {
|
|||
full lbytes;
|
||||
#endif
|
||||
|
||||
void
|
||||
prolog(nlocals) full nlocals; {
|
||||
|
||||
fputs("push ebp\nmov ebp,esp\n", codefile);
|
||||
|
@ -179,6 +180,7 @@ mach_option(s)
|
|||
}
|
||||
#endif /* MACH_OPTIONS */
|
||||
|
||||
void
|
||||
mes(type) word type ; {
|
||||
int argt, a1, a2 ;
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ con_float() {
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
prolog(nlocals) full nlocals; {
|
||||
|
||||
fprintf(codefile,"\tpush\tb\n\tlxi\th,0\n\tdad\tsp\n\tmov\tb,h\n\tmov\tc,l\n");
|
||||
|
@ -67,6 +68,7 @@ prolog(nlocals) full nlocals; {
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
mes(type) word type ; {
|
||||
int argt ;
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ string holstr(n) word n; {
|
|||
full lbytes;
|
||||
#endif
|
||||
|
||||
void
|
||||
prolog(nlocals) full nlocals; {
|
||||
|
||||
fputs("\tpush\tbp\n\tmov\tbp,sp\n", codefile);
|
||||
|
@ -157,6 +158,7 @@ regreturn()
|
|||
}
|
||||
#endif /* REGVARS */
|
||||
|
||||
void
|
||||
mes(type) word type ; {
|
||||
int argt ;
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
* then emitted in one go, by emit_instr().
|
||||
*/
|
||||
|
||||
void move_special();
|
||||
|
||||
emit_instr()
|
||||
{
|
||||
register instr_t *ip;
|
||||
|
@ -70,6 +72,7 @@ long words;
|
|||
T_EMIT2((short)(words), 0, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
ea_1(sz, bits)
|
||||
{
|
||||
/* Because displacements come in three sizes (null displacement,
|
||||
|
@ -242,6 +245,7 @@ badoperand()
|
|||
serror("bad operand(s)");
|
||||
}
|
||||
|
||||
void
|
||||
shift_op(opc, sz)
|
||||
{
|
||||
if (mrg_1 < 010 && mrg_2 < 010) {
|
||||
|
@ -263,6 +267,7 @@ shift_op(opc, sz)
|
|||
ea_2(SIZE_W, MEM|ALT);
|
||||
}
|
||||
|
||||
void
|
||||
bitop(opc)
|
||||
{
|
||||
register bits;
|
||||
|
@ -291,6 +296,7 @@ bitfield(opc, extension)
|
|||
ea_2(SIZE_L, (mrg_2 < 010) ? 0 : (CTR | ALT));
|
||||
}
|
||||
|
||||
void
|
||||
add(opc, sz)
|
||||
{
|
||||
if ((mrg_2 & 070) == 010)
|
||||
|
@ -326,6 +332,7 @@ add(opc, sz)
|
|||
badoperand();
|
||||
}
|
||||
|
||||
void
|
||||
and(opc, sz)
|
||||
{
|
||||
if (mrg_1 == 074 && mrg_2 >= 076) { /* ccr or sr */
|
||||
|
@ -370,6 +377,7 @@ from_dreg(opc, sz, bits)
|
|||
return(1);
|
||||
}
|
||||
|
||||
void
|
||||
cmp(sz)
|
||||
{
|
||||
register opc;
|
||||
|
@ -416,6 +424,7 @@ link_instr(sz, areg)
|
|||
ea_2(sz, 0);
|
||||
}
|
||||
|
||||
void
|
||||
move(sz)
|
||||
{
|
||||
register opc;
|
||||
|
@ -448,6 +457,7 @@ move(sz)
|
|||
ea_2(sz, ALT);
|
||||
}
|
||||
|
||||
void
|
||||
move_special(sz)
|
||||
{
|
||||
if (mrg_2 >= 076) {
|
||||
|
@ -514,6 +524,7 @@ reverse(regs, max)
|
|||
return regs;
|
||||
}
|
||||
|
||||
void
|
||||
movep(sz)
|
||||
{
|
||||
checksize(sz, 2|4);
|
||||
|
@ -530,6 +541,7 @@ movep(sz)
|
|||
badoperand();
|
||||
}
|
||||
|
||||
void
|
||||
branch(opc, exp)
|
||||
expr_t exp;
|
||||
{
|
||||
|
@ -566,6 +578,7 @@ expr_t exp;
|
|||
T_EMIT4(exp.val, exp.typ, RELPC|RELO4, relonami);
|
||||
}
|
||||
|
||||
void
|
||||
cpbcc(opc, exp)
|
||||
expr_t exp;
|
||||
{
|
||||
|
@ -593,6 +606,7 @@ expr_t exp;
|
|||
T_EMIT4(exp.val, exp.typ, RELPC|RELO4, relonami);
|
||||
}
|
||||
|
||||
void
|
||||
ea7071(sz)
|
||||
{
|
||||
mrg_2 = 071;
|
||||
|
@ -671,6 +685,7 @@ ea7071(sz)
|
|||
mrg_2 = 070;
|
||||
}
|
||||
|
||||
void
|
||||
fbranch(opc, exp)
|
||||
expr_t exp;
|
||||
{
|
||||
|
|
|
@ -187,6 +187,7 @@ regsave(s,off,size)
|
|||
fprintf(codefile, "!Local %ld into %s\n",off,s);
|
||||
}
|
||||
|
||||
void
|
||||
prolog(n) full n; {
|
||||
|
||||
nlocals = n;
|
||||
|
@ -207,6 +208,7 @@ mach_option(s)
|
|||
}
|
||||
#endif /* MACH_OPTIONS */
|
||||
|
||||
void
|
||||
mes(type) word type ; {
|
||||
int argt, a1, a2 ;
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#undef word_t
|
||||
#define word_t long
|
||||
|
||||
typedef uint32_t quad;
|
||||
|
||||
#undef ALIGNWORD
|
||||
#define ALIGNWORD 4
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
%token <y_word> OP_RS_RA_NB
|
||||
%token <y_word> OP_RS_RA_RB
|
||||
%token <y_word> OP_RS_RA_RB_C
|
||||
%token <y_word> OP_RS_RA_RA_C
|
||||
%token <y_word> OP_RS_RA_RB_MB5_ME5_C
|
||||
%token <y_word> OP_RS_RA_RB_MB6_C
|
||||
%token <y_word> OP_RS_RA_RB_ME6_C
|
||||
|
@ -80,6 +81,7 @@
|
|||
%token <y_word> OP_TO_RA_RB
|
||||
%token <y_word> OP_TO_RA_SI
|
||||
|
||||
%token <y_word> OP_LA
|
||||
%token <y_word> OP_LI32
|
||||
|
||||
/* Other token types */
|
||||
|
|
|
@ -99,6 +99,9 @@
|
|||
/* Special instructions */
|
||||
|
||||
0, OP_LI32, 0, "li32",
|
||||
0, OP_LA, 0, "la",
|
||||
0, OP_LA, 0, "li",
|
||||
0, OP_RS_RA_RA_C, 31<<26 | 444<<1, "mr",
|
||||
|
||||
/* Branch processor instructions (page 20) */
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ operation
|
|||
| OP_RS_RA_UI_CC C GPR ',' GPR ',' e16 { emit4($1 | ($5<<21) | ($3<<16) | $7); }
|
||||
| OP_RS_RA_RB GPR ',' GPR ',' GPR { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
|
||||
| OP_RS_RA_RB_C c GPR ',' GPR ',' GPR { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11)); }
|
||||
| OP_RS_RA_RA_C c GPR ',' GPR { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($5<<11)); }
|
||||
| OP_RS_RA_RB_MB5_ME5_C c GPR ',' GPR ',' GPR ',' u5 ',' u5 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | ($9<<6) | ($11<<1)); }
|
||||
| OP_RS_RA_RB_MB6_C c GPR ',' GPR ',' GPR ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | (($9&0x1F)<<6) | (($9&0x20)>>0)); }
|
||||
| OP_RS_RA_RB_ME6_C c GPR ',' GPR ',' GPR ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | (($9&0x1F)<<6) | (($9&0x20)>>0)); }
|
||||
|
@ -196,9 +197,16 @@ bda
|
|||
li32
|
||||
: GPR ',' expr
|
||||
{
|
||||
newrelo($3.typ, RELOPPC | FIXUPFLAGS);
|
||||
emit4((15<<26) | ($1<<21) | (0<<16) | ($3.val >> 16)); /* addis */
|
||||
emit4((24<<26) | ($1<<21) | ($1<<16) | ($3.val & 0xffff)); /* ori */
|
||||
quad type = $3.typ & S_TYP;
|
||||
quad val = $3.val;
|
||||
if ((type == S_ABS) && (val <= 0xffff))
|
||||
emit4((14<<26) | ($1<<21) | (0<<16) | val); /* addi */
|
||||
else
|
||||
{
|
||||
newrelo($3.typ, RELOPPC | FIXUPFLAGS);
|
||||
emit4((15<<26) | ($1<<21) | (0<<16) | (val >> 16)); /* addis */
|
||||
emit4((24<<26) | ($1<<21) | ($1<<16) | (val & 0xffff)); /* ori */
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
for _, plat in ipairs(vars.plats) do
|
||||
acklibrary {
|
||||
name = "headers_"..plat,
|
||||
hdrs = { "./*.h" }
|
||||
}
|
||||
|
||||
acklibrary {
|
||||
name = "lib_"..plat,
|
||||
srcs = {
|
||||
"./*.s",
|
||||
"./*.e",
|
||||
},
|
||||
vars = { plat = plat },
|
||||
deps = {
|
||||
"h+emheaders"
|
||||
"h+emheaders",
|
||||
"+headers_"..plat,
|
||||
}
|
||||
}
|
||||
end
|
||||
|
|
|
@ -12,11 +12,14 @@
|
|||
! address and jumps to it.
|
||||
! traps if resulting address is zero
|
||||
!
|
||||
! On entry: r3 = address of CSA table
|
||||
! r4 = value
|
||||
! Stack: ( value tableaddr -- )
|
||||
|
||||
.define .csa
|
||||
.csa:
|
||||
lwz r3, 0(sp)
|
||||
lwz r4, 4(sp)
|
||||
addi sp, sp, 8
|
||||
|
||||
lwz r5, 0(r3) ! load default
|
||||
mtspr ctr, r5
|
||||
|
||||
|
|
|
@ -12,11 +12,14 @@
|
|||
! address and jumps to it.
|
||||
! traps if resulting address is zero
|
||||
!
|
||||
! On entry: r3 = address of CSB table
|
||||
! r4 = value
|
||||
! Stack: ( value tableaddr -- )
|
||||
|
||||
.define .csb
|
||||
.csb:
|
||||
lwz r3, 0(sp)
|
||||
lwz r4, 4(sp)
|
||||
addi sp, sp, 8
|
||||
|
||||
lwz r5, 0(r3) ! load default
|
||||
mtspr ctr, r5
|
||||
|
||||
|
|
26
mach/powerpc/libem/inn.s
Normal file
26
mach/powerpc/libem/inn.s
Normal file
|
@ -0,0 +1,26 @@
|
|||
#include "powerpc.h"
|
||||
|
||||
.sect .text
|
||||
|
||||
/* Tests a bit in a bitset on the stack.
|
||||
*
|
||||
* Stack: ( bitset bitnum setsize -- bool )
|
||||
*/
|
||||
|
||||
.define .inn
|
||||
.inn:
|
||||
lwz r3, 0(sp) /* r3 = size (bytes) */
|
||||
lwz r4, 4(sp) /* r4 = bit number */
|
||||
addi r5, sp, 8 /* r5 = base address of bit set */
|
||||
|
||||
srawi r6, r4, 3 /* r6 = byte address into set */
|
||||
andi. r7, r4, 7 /* r7 = bit within byte */
|
||||
|
||||
lbzx r8, r5, r6 /* r8 = individual byte from set */
|
||||
sraw r8, r8, r7
|
||||
rlwinm r8, r8, 0, 31, 31
|
||||
|
||||
addi sp, sp, 8 /* retract over the two words */
|
||||
add sp, sp, r3 /* retract over bitfield */
|
||||
stwu r8, -4(sp) /* push result */
|
||||
bclr ALWAYS, 0, 0 /* return */
|
333
mach/powerpc/mcg/platform.c
Normal file
333
mach/powerpc/mcg/platform.c
Normal file
|
@ -0,0 +1,333 @@
|
|||
#include "mcg.h"
|
||||
|
||||
/* mcg stack frames are laid out as:
|
||||
*
|
||||
* | ...params...
|
||||
* | --------------- <- ab
|
||||
* | old FR
|
||||
* | old FP
|
||||
* | --------------- <- fp (a.k.a. lb)
|
||||
* | locals
|
||||
* | ---------------
|
||||
* | spills
|
||||
* | --------------- <- sb
|
||||
* | saved regs
|
||||
* | --------------- <- sp, rb
|
||||
* V ...user area...
|
||||
*
|
||||
* st indexes up; lb indexes down.
|
||||
*
|
||||
* Note that [fp] == old_fp and ab == fp + 8.
|
||||
*/
|
||||
|
||||
static ARRAYOF(struct hreg) saved_regs;
|
||||
|
||||
void platform_calculate_offsets(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
saved_regs.count = 0;
|
||||
for (i=0; i<current_proc->usedregs.count; i++)
|
||||
{
|
||||
struct hreg* hreg = current_proc->usedregs.item[i];
|
||||
|
||||
if (!(hreg->attrs & burm_volatile_ATTR) &&
|
||||
((hreg->attrs & burm_long_ATTR) || (hreg->attrs & burm_double_ATTR)))
|
||||
{
|
||||
hreg->offset = current_proc->saved_size;
|
||||
current_proc->saved_size += 8;
|
||||
array_append(&saved_regs, hreg);
|
||||
}
|
||||
}
|
||||
for (i=0; i<current_proc->usedregs.count; i++)
|
||||
{
|
||||
struct hreg* hreg = current_proc->usedregs.item[i];
|
||||
|
||||
if (!(hreg->attrs & burm_volatile_ATTR) &&
|
||||
((hreg->attrs & burm_int_ATTR) || (hreg->attrs & burm_float_ATTR)))
|
||||
{
|
||||
hreg->offset = current_proc->saved_size;
|
||||
current_proc->saved_size += 4;
|
||||
array_append(&saved_regs, hreg);
|
||||
}
|
||||
}
|
||||
|
||||
current_proc->fp_to_ab = 8;
|
||||
current_proc->fp_to_lb = 0;
|
||||
current_proc->fp_to_sb = -(current_proc->locals_size + current_proc->spills_size);
|
||||
current_proc->fp_to_rb = current_proc->fp_to_sb - current_proc->saved_size;
|
||||
}
|
||||
|
||||
struct hop* platform_prologue(void)
|
||||
{
|
||||
int i;
|
||||
int spoffset = current_proc->saved_size + current_proc->spills_size +
|
||||
current_proc->locals_size;
|
||||
struct hop* hop = new_hop(current_proc->entry, NULL);
|
||||
|
||||
hop_add_insel(hop, "! locals_size = %d", current_proc->locals_size);
|
||||
hop_add_insel(hop, "! spills_size = %d", current_proc->spills_size);
|
||||
hop_add_insel(hop, "! saved_size = %d", current_proc->saved_size);
|
||||
hop_add_insel(hop, "! params @ fp+%d", current_proc->fp_to_ab);
|
||||
hop_add_insel(hop, "! lr @ fp+4");
|
||||
hop_add_insel(hop, "! fp @ fp+0");
|
||||
hop_add_insel(hop, "! locals @ fp-%d to fp+0",
|
||||
current_proc->locals_size);
|
||||
hop_add_insel(hop, "! spills @ fp-%d to fp-%d",
|
||||
-current_proc->fp_to_sb, current_proc->locals_size);
|
||||
for (i=saved_regs.count-1; i>=0; i--)
|
||||
{
|
||||
struct hreg* hreg = saved_regs.item[i];
|
||||
hop_add_insel(hop, "! %s @ fp-%d",
|
||||
hreg->id, -(current_proc->fp_to_rb + hreg->offset));
|
||||
}
|
||||
|
||||
hop_add_insel(hop, "addi sp, sp, %d", -(spoffset + 8));
|
||||
hop_add_insel(hop, "mfspr r0, lr");
|
||||
hop_add_insel(hop, "stw fp, %d(sp)", spoffset + 0);
|
||||
hop_add_insel(hop, "stw r0, %d(sp)", spoffset + 4);
|
||||
hop_add_insel(hop, "addi fp, sp, %d", spoffset);
|
||||
|
||||
/* Saved reg offsets are negative. */
|
||||
for (i=0; i<saved_regs.count; i++)
|
||||
{
|
||||
struct hreg* hreg = saved_regs.item[i];
|
||||
if (hreg->attrs & burm_int_ATTR)
|
||||
hop_add_insel(hop, "stw %H, %d(fp)",
|
||||
hreg, current_proc->fp_to_rb + hreg->offset);
|
||||
else if (hreg->attrs & burm_float_ATTR)
|
||||
hop_add_insel(hop, "stfs %H, %d(fp)",
|
||||
hreg, current_proc->fp_to_rb + hreg->offset);
|
||||
}
|
||||
return hop;
|
||||
}
|
||||
|
||||
struct hop* platform_epilogue(void)
|
||||
{
|
||||
struct hop* hop = new_hop(current_proc->exit, NULL);
|
||||
int i;
|
||||
|
||||
for (i=0; i<saved_regs.count; i++)
|
||||
{
|
||||
struct hreg* hreg = saved_regs.item[i];
|
||||
if (hreg->attrs & burm_int_ATTR)
|
||||
hop_add_insel(hop, "lwz %H, %d(fp)",
|
||||
hreg, current_proc->fp_to_rb + hreg->offset);
|
||||
else if (hreg->attrs & burm_float_ATTR)
|
||||
hop_add_insel(hop, "lfs %H, %d(fp)",
|
||||
hreg, current_proc->fp_to_rb + hreg->offset);
|
||||
}
|
||||
|
||||
hop_add_insel(hop, "lwz r0, 4(fp)");
|
||||
hop_add_insel(hop, "mtspr lr, r0");
|
||||
hop_add_insel(hop, "lwz r0, 0(fp)"); /* load old fp */
|
||||
hop_add_insel(hop, "addi sp, fp, %d", current_proc->fp_to_ab);
|
||||
hop_add_insel(hop, "mr fp, r0");
|
||||
hop_add_insel(hop, "bclr 20, 0, 0");
|
||||
|
||||
return hop;
|
||||
}
|
||||
|
||||
struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg* dest)
|
||||
{
|
||||
struct hop* hop = new_hop(bb, NULL);
|
||||
|
||||
if ((src->attrs & TYPE_ATTRS) != (dest->attrs & TYPE_ATTRS))
|
||||
{
|
||||
assert(!src->is_stacked);
|
||||
assert(!dest->is_stacked);
|
||||
|
||||
switch (src->attrs & TYPE_ATTRS)
|
||||
{
|
||||
case burm_int_ATTR:
|
||||
hop_add_insel(hop, "stwu %H, -4(sp)", src);
|
||||
break;
|
||||
|
||||
case burm_long_ATTR:
|
||||
hop_add_insel(hop, "stwu %0H, -4(sp)", src);
|
||||
hop_add_insel(hop, "stwu %1H, -4(sp)", src);
|
||||
break;
|
||||
|
||||
case burm_float_ATTR:
|
||||
hop_add_insel(hop, "stfsu %H, -4(sp)", src);
|
||||
break;
|
||||
|
||||
case burm_double_ATTR:
|
||||
hop_add_insel(hop, "stfdu %H, -8(sp)", src);
|
||||
break;
|
||||
|
||||
default:
|
||||
goto nomove;
|
||||
}
|
||||
|
||||
switch (dest->attrs & TYPE_ATTRS)
|
||||
{
|
||||
case burm_int_ATTR:
|
||||
hop_add_insel(hop, "lwz %H, 0(sp)", dest);
|
||||
break;
|
||||
|
||||
case burm_long_ATTR:
|
||||
hop_add_insel(hop, "lwz %0H, 4(sp)", dest);
|
||||
hop_add_insel(hop, "lwz %1H, 0(sp)", dest);
|
||||
break;
|
||||
|
||||
case burm_float_ATTR:
|
||||
hop_add_insel(hop, "lfs %H, 0(sp)", dest);
|
||||
break;
|
||||
|
||||
case burm_double_ATTR:
|
||||
hop_add_insel(hop, "lfd %H, 0(sp)", dest);
|
||||
break;
|
||||
|
||||
default:
|
||||
goto nomove;
|
||||
}
|
||||
|
||||
switch (dest->attrs & TYPE_ATTRS)
|
||||
{
|
||||
case burm_int_ATTR:
|
||||
case burm_float_ATTR:
|
||||
hop_add_insel(hop, "addi sp, sp, 4");
|
||||
break;
|
||||
|
||||
case burm_double_ATTR:
|
||||
case burm_long_ATTR:
|
||||
hop_add_insel(hop, "addi sp, sp, 8");
|
||||
break;
|
||||
|
||||
default:
|
||||
goto nomove;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t type = src->attrs & TYPE_ATTRS;
|
||||
|
||||
if (!src->is_stacked && dest->is_stacked)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case burm_int_ATTR:
|
||||
hop_add_insel(hop, "stw %H, %S(fp) ! %H", src, dest, dest);
|
||||
break;
|
||||
|
||||
case burm_float_ATTR:
|
||||
hop_add_insel(hop, "stfs %H, %S(fp) ! %H", src, dest, dest);
|
||||
break;
|
||||
|
||||
case burm_long_ATTR:
|
||||
hop_add_insel(hop, "stw %0H, 4+%S(fp) ! %H", src, dest, dest);
|
||||
hop_add_insel(hop, "stw %1H, 0+%S(fp) ! %H", src, dest, dest);
|
||||
break;
|
||||
|
||||
case burm_double_ATTR:
|
||||
hop_add_insel(hop, "stfd %H, %S(fp) ! %H", src, dest, dest);
|
||||
break;
|
||||
|
||||
default:
|
||||
goto nomove;
|
||||
}
|
||||
}
|
||||
else if (src->is_stacked && !dest->is_stacked)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case burm_int_ATTR:
|
||||
hop_add_insel(hop, "lwz %H, %S(fp) ! %H", dest, src, src);
|
||||
break;
|
||||
|
||||
case burm_float_ATTR:
|
||||
hop_add_insel(hop, "lfs %H, %S(fp) ! %H", dest, src, src);
|
||||
break;
|
||||
|
||||
case burm_double_ATTR:
|
||||
hop_add_insel(hop, "lfd %H, %S(fp) ! %H", dest, src, src);
|
||||
break;
|
||||
|
||||
default:
|
||||
goto nomove;
|
||||
}
|
||||
}
|
||||
else if (!src->is_stacked && !dest->is_stacked)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case burm_int_ATTR:
|
||||
hop_add_insel(hop, "mr %H, %H", dest, src);
|
||||
break;
|
||||
|
||||
case burm_long_ATTR:
|
||||
hop_add_insel(hop, "mr %0H, %0H", dest, src);
|
||||
hop_add_insel(hop, "mr %1H, %1H", dest, src);
|
||||
break;
|
||||
|
||||
case burm_float_ATTR:
|
||||
case burm_double_ATTR:
|
||||
hop_add_insel(hop, "fmr %H, %H", dest, src);
|
||||
break;
|
||||
|
||||
default:
|
||||
goto nomove;
|
||||
}
|
||||
}
|
||||
else
|
||||
goto nomove;
|
||||
}
|
||||
|
||||
return hop;
|
||||
|
||||
nomove:
|
||||
fatal("cannot move %s to %s", src->id, dest->id);
|
||||
}
|
||||
|
||||
struct hop* platform_swap(struct basicblock* bb, struct hreg* src, struct hreg* dest)
|
||||
{
|
||||
struct hop* hop = new_hop(bb, NULL);
|
||||
|
||||
assert(!src->is_stacked);
|
||||
assert(!dest->is_stacked);
|
||||
assert((src->attrs & TYPE_ATTRS) == (dest->attrs & TYPE_ATTRS));
|
||||
|
||||
switch (src->attrs & TYPE_ATTRS)
|
||||
{
|
||||
case burm_int_ATTR:
|
||||
hop_add_insel(hop, "mr r0, %H", src);
|
||||
hop_add_insel(hop, "mr %H, %H", src, dest);
|
||||
hop_add_insel(hop, "mr %H, r0", dest);
|
||||
break;
|
||||
|
||||
case burm_long_ATTR:
|
||||
hop_add_insel(hop, "mr r0, %0H", src);
|
||||
hop_add_insel(hop, "mr %0H, %0H", src, dest);
|
||||
hop_add_insel(hop, "mr %0H, r0", dest);
|
||||
|
||||
hop_add_insel(hop, "mr r0, %1H", src);
|
||||
hop_add_insel(hop, "mr %1H, %1H", src, dest);
|
||||
hop_add_insel(hop, "mr %1H, r0", dest);
|
||||
break;
|
||||
|
||||
case burm_float_ATTR:
|
||||
case burm_double_ATTR:
|
||||
hop_add_insel(hop, "fmr f0, %H", src);
|
||||
hop_add_insel(hop, "fmr %H, %H", src, dest);
|
||||
hop_add_insel(hop, "fmr %H, f0", dest);
|
||||
break;
|
||||
}
|
||||
|
||||
return hop;
|
||||
}
|
||||
|
||||
const char* platform_label(const char* label)
|
||||
{
|
||||
/* Labels starting with . are internal, not exported, and don't need mangling. */
|
||||
|
||||
if (label[0] == '.')
|
||||
return label;
|
||||
|
||||
/* Otherwise, mangle. */
|
||||
|
||||
return aprintf("_%s", label);
|
||||
}
|
||||
|
||||
/* vim: set sw=4 ts=4 expandtab : */
|
||||
|
794
mach/powerpc/mcg/table
Normal file
794
mach/powerpc/mcg/table
Normal file
|
@ -0,0 +1,794 @@
|
|||
REGISTERS
|
||||
|
||||
/* Registers are allocated top down; the order here is odd in order to make
|
||||
* sure that non-volatile registers get allocated from r31 (or f31) down.
|
||||
*
|
||||
* Attributes may have at most one of: int, float, long, double. These
|
||||
* indicate that the register is used to store a value of that type. If
|
||||
* your register can store more than one type, create an alias. Registers
|
||||
* with none of these cannot be copied by the code generator (and so cannot
|
||||
* be moved from register to register or spilt).
|
||||
*/
|
||||
|
||||
r12 int volatile;
|
||||
r11 int volatile;
|
||||
r10 int volatile;
|
||||
r9 int volatile;
|
||||
r8 int volatile;
|
||||
r7 int volatile;
|
||||
r6 int volatile;
|
||||
r5 int volatile;
|
||||
r4 int volatile;
|
||||
r3 int volatile iret;
|
||||
|
||||
r31 int;
|
||||
r30 int;
|
||||
r29 int;
|
||||
r28 int;
|
||||
r27 int;
|
||||
r26 int;
|
||||
r25 int;
|
||||
r24 int;
|
||||
r23 int;
|
||||
r22 int;
|
||||
r21 int;
|
||||
r20 int;
|
||||
r19 int;
|
||||
r18 int;
|
||||
r17 int;
|
||||
r16 int;
|
||||
r15 int;
|
||||
r14 int;
|
||||
r13 int;
|
||||
|
||||
r11r12 named("r11", "r12") aliases(r11, r12) long volatile;
|
||||
r9r10 named("r9", "r10") aliases(r9, r10) long volatile;
|
||||
r7r8 named("r7", "r8") aliases(r7, r8) long volatile;
|
||||
r5r6 named("r5", "r6") aliases(r6, r6) long volatile;
|
||||
r3r4 named("r3", "r4") aliases(r3, r4) long volatile lret;
|
||||
|
||||
r29r30 named("r29", "r30") aliases(r29, r30) long;
|
||||
r27r28 named("r27", "r28") aliases(r27, r28) long;
|
||||
r25r26 named("r25", "r26") aliases(r25, r26) long;
|
||||
r23r24 named("r23", "r24") aliases(r23, r24) long;
|
||||
r21r22 named("r21", "r22") aliases(r21, r22) long;
|
||||
r19r20 named("r19", "r20") aliases(r19, r20) long;
|
||||
r17r18 named("r17", "r18") aliases(r17, r18) long;
|
||||
r15r16 named("r15", "r16") aliases(r15, r16) long;
|
||||
r13r14 named("r13", "r14") aliases(r13, r14) long;
|
||||
|
||||
f14 float volatile;
|
||||
f13 float volatile;
|
||||
f12 float volatile;
|
||||
f11 float volatile;
|
||||
f10 float volatile;
|
||||
f9 float volatile;
|
||||
f8 float volatile;
|
||||
f7 float volatile;
|
||||
f6 float volatile;
|
||||
f5 float volatile;
|
||||
f4 float volatile;
|
||||
f3 float volatile fret;
|
||||
f2 float volatile;
|
||||
f1 float volatile;
|
||||
f0 float volatile;
|
||||
|
||||
f31 float;
|
||||
f30 float;
|
||||
f29 float;
|
||||
f28 float;
|
||||
f27 float;
|
||||
f26 float;
|
||||
f25 float;
|
||||
f24 float;
|
||||
f23 float;
|
||||
f22 float;
|
||||
f21 float;
|
||||
f20 float;
|
||||
f19 float;
|
||||
f18 float;
|
||||
f17 float;
|
||||
f16 float;
|
||||
f15 float;
|
||||
|
||||
d14 named("f14") aliases(f14) double volatile;
|
||||
d13 named("f13") aliases(f13) double volatile;
|
||||
d12 named("f12") aliases(f12) double volatile;
|
||||
d11 named("f11") aliases(f11) double volatile;
|
||||
d10 named("f10") aliases(f10) double volatile;
|
||||
d9 named("f9") aliases(f9) double volatile;
|
||||
d8 named("f8") aliases(f8) double volatile;
|
||||
d7 named("f7") aliases(f7) double volatile;
|
||||
d6 named("f6") aliases(f6) double volatile;
|
||||
d5 named("f5") aliases(f5) double volatile;
|
||||
d4 named("f4") aliases(f4) double volatile;
|
||||
d3 named("f3") aliases(f3) double volatile dret;
|
||||
d2 named("f2") aliases(f2) double volatile;
|
||||
d1 named("f1") aliases(f1) double volatile;
|
||||
d0 named("f0") aliases(f0) double volatile;
|
||||
|
||||
d31 named("f31") aliases(f31) double;
|
||||
d30 named("f30") aliases(f30) double;
|
||||
d29 named("f29") aliases(f29) double;
|
||||
d28 named("f28") aliases(f28) double;
|
||||
d27 named("f27") aliases(f27) double;
|
||||
d26 named("f26") aliases(f26) double;
|
||||
d25 named("f25") aliases(f25) double;
|
||||
d24 named("f24") aliases(f24) double;
|
||||
d23 named("f23") aliases(f23) double;
|
||||
d22 named("f22") aliases(f22) double;
|
||||
d21 named("f21") aliases(f21) double;
|
||||
d20 named("f20") aliases(f20) double;
|
||||
d19 named("f19") aliases(f19) double;
|
||||
d18 named("f18") aliases(f18) double;
|
||||
d17 named("f17") aliases(f17) double;
|
||||
d16 named("f16") aliases(f16) double;
|
||||
d15 named("f15") aliases(f15) double;
|
||||
|
||||
cr0 cr;
|
||||
|
||||
|
||||
|
||||
DECLARATIONS
|
||||
|
||||
cr;
|
||||
ubyteX; /* bottom 8 bits valid, the rest undefined */
|
||||
ubyte0; /* bottom 8 bits valid, the rest 0 */
|
||||
ushortX; /* bottom 16 bits valid, the rest undefined */
|
||||
ushort0; /* bottom 16 bits valid, the rest 0 */
|
||||
|
||||
address fragment;
|
||||
|
||||
|
||||
|
||||
PATTERNS
|
||||
|
||||
/* Special */
|
||||
|
||||
PAIR(BLOCK.I, BLOCK.I);
|
||||
|
||||
|
||||
|
||||
/* Miscellaneous special things */
|
||||
|
||||
PUSH.I(in:(int)reg)
|
||||
emit "stwu %in, -4(sp)"
|
||||
cost 4;
|
||||
|
||||
PUSH.L(in:(long)reg)
|
||||
emit "stwu %in.0, -4(sp)"
|
||||
emit "stwu %in.1, -4(sp)"
|
||||
cost 8;
|
||||
|
||||
PUSH.D(in:(double)reg)
|
||||
emit "stfdu %in, -8(sp)"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = POP.I
|
||||
emit "lwz %out, 0(sp)"
|
||||
emit "addi sp, sp, 4"
|
||||
cost 8;
|
||||
|
||||
out:(long)reg = POP.L
|
||||
emit "lwz %out.0, 4(sp)"
|
||||
emit "lwz %out.1, 0(sp)"
|
||||
emit "addi sp, sp, 8"
|
||||
cost 12;
|
||||
|
||||
out:(float)reg = POP.F
|
||||
emit "lfs %out, 0(sp)"
|
||||
emit "addi sp, sp, 4"
|
||||
cost 8;
|
||||
|
||||
out:(double)reg = POP.D
|
||||
emit "lfd %out, 0(sp)"
|
||||
emit "addi sp, sp, 8"
|
||||
cost 8;
|
||||
|
||||
SETRET.I(in:(iret)reg)
|
||||
emit "! setret4"
|
||||
cost 1;
|
||||
|
||||
SETRET.L(in:(lret)reg)
|
||||
emit "! setret8"
|
||||
cost 1;
|
||||
|
||||
STACKADJUST.I(delta:CONST.I)
|
||||
when signed_constant(%delta, 16)
|
||||
emit "addi sp, sp, $delta"
|
||||
cost 4;
|
||||
|
||||
STACKADJUST.I(in:(int)reg)
|
||||
emit "add sp, sp, %in"
|
||||
cost 4;
|
||||
|
||||
STACKADJUST.I(NEG.I(in:(int)reg))
|
||||
emit "subf sp, %in, sp"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = GETFP.I
|
||||
emit "mr %out, fp"
|
||||
cost 4;
|
||||
|
||||
SETFP.I(in:(int)reg)
|
||||
emit "mr fp, %in"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = CHAINFP.I(in:(int)reg)
|
||||
emit "lwz %out, 0(%in)"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = FPTOAB.I(GETFP.I)
|
||||
emit "addi %out, fp, 8"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = FPTOAB.I(in:(int)reg)
|
||||
emit "addi %out, %in, 8"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = FPTOLB.I(in:(int)reg)
|
||||
with %out == %in
|
||||
cost 1;
|
||||
|
||||
out:(int)reg = GETSP.I
|
||||
emit "mr %out, sp"
|
||||
cost 4;
|
||||
|
||||
SETSP.I(in:(int)reg)
|
||||
emit "mr sp, %in"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = ANY.I
|
||||
cost 1;
|
||||
|
||||
out:(int)reg = COPYF.I(in:(float)reg)
|
||||
emit "stfsu %in, -4(sp)"
|
||||
emit "lwz %out, 0(sp)"
|
||||
emit "addi sp, sp, 4"
|
||||
cost 12;
|
||||
|
||||
out:(double)reg = COPYL.D(in:(long)reg)
|
||||
emit "stwu %in.0, -4(sp)"
|
||||
emit "stwu %in.1, -4(sp)"
|
||||
emit "lfd %out, 0(sp)"
|
||||
emit "addi sp, sp, 8"
|
||||
cost 16;
|
||||
|
||||
out:(long)reg = COPYD.L(in:(double)reg)
|
||||
emit "stfdu %in, -8(sp)"
|
||||
emit "lwz %out.0, 4(sp)"
|
||||
emit "lwz %out.1, 0(sp)"
|
||||
emit "addi sp, sp, 8"
|
||||
cost 16;
|
||||
|
||||
|
||||
|
||||
/* Memory operations */
|
||||
|
||||
/* Stores */
|
||||
|
||||
STORE.D(addr:address, value:(double)reg)
|
||||
emit "stfd %value, %addr"
|
||||
cost 4;
|
||||
|
||||
STORE.L(addr:address, value:(long)reg)
|
||||
emit "stw %value.0, 4+%addr"
|
||||
emit "stw %value.1, 0+%addr"
|
||||
cost 8;
|
||||
|
||||
STORE.I(addr:address, value:(int)reg)
|
||||
emit "stw %value, %addr"
|
||||
cost 4;
|
||||
|
||||
STOREH.I(addr:address, value:(int)ushortX)
|
||||
emit "sth %value, %addr"
|
||||
cost 4;
|
||||
|
||||
STOREH.I(ADD.I(left:(int)reg, right:(int)reg), value:(int)ushortX)
|
||||
emit "sthx %value, %left, %right"
|
||||
cost 4;
|
||||
|
||||
STOREB.I(addr:address, value:(int)ushortX)
|
||||
emit "sth %value, %addr"
|
||||
cost 4;
|
||||
|
||||
STOREB.I(addr:address, value:(int)ubyteX)
|
||||
emit "stb %value, %addr"
|
||||
cost 4;
|
||||
|
||||
STOREB.I(ADD.I(left:(int)reg, right:(int)reg), value:(int)ubyteX)
|
||||
emit "stbx %value, %left, %right"
|
||||
cost 4;
|
||||
|
||||
/* Loads */
|
||||
|
||||
out:(int)reg = LOAD.I(addr:address)
|
||||
emit "lwz %out, %addr"
|
||||
cost 4;
|
||||
|
||||
out:(long)reg = LOAD.L(addr:address)
|
||||
emit "lwz %out.0, 4+%addr"
|
||||
emit "lwz %out.1, 0+%addr"
|
||||
cost 8;
|
||||
|
||||
out:(int)ushort0 = LOADH.I(addr:address)
|
||||
emit "lhz %out, %addr"
|
||||
cost 4;
|
||||
|
||||
out:(int)ubyte0 = LOADB.I(addr:address)
|
||||
emit "lbz %out, %addr"
|
||||
cost 4;
|
||||
|
||||
/* ubyte intrinsics */
|
||||
|
||||
out:(int)ubyteX = in:(int)ubyte0
|
||||
with %out == %in
|
||||
emit "! ubyte0 -> ubyteX"
|
||||
cost 1;
|
||||
|
||||
out:(int)ubyte0 = in:(int)ubyteX
|
||||
emit "andi %out, %in, 0xff ! ubyteX -> ubyte0"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = in:(int)ubyte0
|
||||
with %out == %in
|
||||
emit "! ubyte0 -> reg"
|
||||
cost 4;
|
||||
|
||||
out:(int)ubyteX = in:(int)reg
|
||||
with %out == %in
|
||||
emit "! reg -> ubyteX"
|
||||
cost 1;
|
||||
|
||||
/* ushort intrinsics */
|
||||
|
||||
out:(int)ushortX = in:(int)ushort0
|
||||
with %out == %in
|
||||
emit "! ushort0 -> ushortX"
|
||||
cost 1;
|
||||
|
||||
out:(int)ushort0 = in:(int)ushortX
|
||||
emit "andi %out, %in, 0xff ! ushortX -> ushort0"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = in:(int)ushort0
|
||||
with %out == %in
|
||||
emit "! ushort0 -> reg"
|
||||
cost 4;
|
||||
|
||||
out:(int)ushortX = in:(int)reg
|
||||
with %out == %in
|
||||
emit "! reg -> ushortX"
|
||||
cost 1;
|
||||
|
||||
|
||||
/* Extensions and conversions */
|
||||
|
||||
out:(int)reg = EXTENDB.I(in:(int)reg)
|
||||
emit "extsb %out, %in"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = EXTENDH.I(in:(int)reg)
|
||||
emit "extsh %out, %in"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = FROMSI.I(in:(int)reg)
|
||||
with %out == %in
|
||||
emit "! FROMSI.I(int) -> int"
|
||||
cost 1;
|
||||
|
||||
out:(int)reg = FROMUI.I(in:(int)reg)
|
||||
with %out == %in
|
||||
emit "! FROMUI.I(int) -> int"
|
||||
cost 1;
|
||||
|
||||
out:(long)reg = FROMSI.L(in:(int)reg)
|
||||
emit "mr %out.0, %in"
|
||||
emit "srawi %out.1, %out.0, 31"
|
||||
cost 8;
|
||||
|
||||
out:(long)reg = FROMUI.L(in:(int)reg)
|
||||
emit "mr %out.0, %in"
|
||||
emit "li32 %out.1, 0"
|
||||
cost 8;
|
||||
|
||||
out:(iret)reg = FROMSF.I(in:(dret)reg)
|
||||
with corrupted(volatile)
|
||||
emit "bl .fromf2i"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = FROMSD.I(in:(double)reg)
|
||||
with preserved(%in)
|
||||
emit "fctiwz %in, %in"
|
||||
emit "stfdu %in, -8(sp)"
|
||||
emit "lwz %out, 4(sp)"
|
||||
emit "addi sp, sp, 8"
|
||||
cost 16;
|
||||
|
||||
out:(int)reg = FROMUD.I(in:(double)reg)
|
||||
with corrupted(volatile)
|
||||
emit "stfdu %in, -8(sp)"
|
||||
emit "bl .cfu8"
|
||||
emit "lwz %out, 0(sp)"
|
||||
emit "addi sp, sp, 4"
|
||||
cost 16;
|
||||
|
||||
out:(lret)reg = FROMSF.L(in:(fret)reg)
|
||||
with corrupted(volatile)
|
||||
emit "bl .fromf2l"
|
||||
cost 4;
|
||||
|
||||
out:(lret)reg = FROMUF.I(in:(fret)reg)
|
||||
with corrupted(volatile)
|
||||
emit "bl .fromf2l"
|
||||
cost 4;
|
||||
|
||||
out:(double)reg = FROMSI.D(in:(int)reg)
|
||||
with corrupted(volatile)
|
||||
emit "stwu %in, -4(sp)"
|
||||
emit "bl .cif8"
|
||||
emit "lfd %out, 0(sp)"
|
||||
emit "addi sp, sp, 8"
|
||||
cost 4;
|
||||
|
||||
out:(fret)reg = FROMUI.F(in:(iret)reg)
|
||||
with corrupted(volatile)
|
||||
emit "bl .fromui2f"
|
||||
cost 4;
|
||||
|
||||
out:(double)reg = FROMUI.D(in:(int)reg)
|
||||
with corrupted(volatile)
|
||||
emit "stwu %in, -4(sp)"
|
||||
emit "bl .cuf8"
|
||||
emit "lfd %out, 0(sp)"
|
||||
emit "addi sp, sp, 8"
|
||||
cost 4;
|
||||
|
||||
out:(lret)reg = FROMIPAIR.L(in1:(int)reg, in2:(int)reg)
|
||||
emit "mr %out.0, %in1"
|
||||
emit "mr %out.1, %in2"
|
||||
cost 8;
|
||||
|
||||
out:(int)reg = FROML0.I(in:(long)reg)
|
||||
emit "mr %out, %in.0"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = FROML1.I(in:(long)reg)
|
||||
emit "mr %out, %in.1"
|
||||
cost 4;
|
||||
|
||||
|
||||
|
||||
/* Locals */
|
||||
|
||||
out:(int)reg = in:LOCAL.I
|
||||
emit "addi %out, fp, $in"
|
||||
cost 4;
|
||||
|
||||
address = in:LOCAL.I
|
||||
emit "$in(fp)";
|
||||
|
||||
|
||||
|
||||
|
||||
/* Memory addressing modes */
|
||||
|
||||
address = ADD.I(addr:(int)reg, offset:CONST.I)
|
||||
when signed_constant(%offset, 16)
|
||||
emit "$offset(%addr)";
|
||||
|
||||
address = addr:(int)reg
|
||||
emit "0(%addr)";
|
||||
|
||||
|
||||
|
||||
/* Branches */
|
||||
|
||||
JUMP(addr:BLOCK.I)
|
||||
emit "b $addr"
|
||||
cost 4;
|
||||
|
||||
FARJUMP(addr:LABEL.I)
|
||||
with corrupted(volatile)
|
||||
emit "b $addr"
|
||||
cost 4;
|
||||
|
||||
JUMP(dest:(int)reg)
|
||||
emit "mtspr ctr, %dest"
|
||||
emit "bcctrl 20, 0, 0"
|
||||
cost 8;
|
||||
|
||||
CJUMPEQ(value:(cr)cr, PAIR(true:BLOCK.I, false:BLOCK.I))
|
||||
emit "bc 12, 2, $true" /* IFTRUE EQ */
|
||||
emit "b $false"
|
||||
cost 8;
|
||||
|
||||
CJUMPLE(value:(cr)cr, PAIR(true:BLOCK.I, false:BLOCK.I))
|
||||
emit "bc 4, 1, $true" /* IFFALSE GT */
|
||||
emit "b $false"
|
||||
cost 8;
|
||||
|
||||
CJUMPLT(value:(cr)cr, PAIR(true:BLOCK.I, false:BLOCK.I))
|
||||
emit "bc 12, 0, $true" /* IFTRUE LT */
|
||||
emit "b $false"
|
||||
cost 8;
|
||||
|
||||
#define CALLLABEL(insn) \
|
||||
insn (dest:LABEL.I) \
|
||||
with corrupted(volatile) \
|
||||
emit "bl $dest" \
|
||||
cost 4;
|
||||
|
||||
CALLLABEL(CALL)
|
||||
out:(iret)reg = CALLLABEL(CALL.I)
|
||||
out:(lret)reg = CALLLABEL(CALL.L)
|
||||
|
||||
#define CALLINDIRECT(insn) \
|
||||
insn (dest:(int)reg) \
|
||||
with corrupted(volatile) \
|
||||
emit "mtspr ctr, %dest" \
|
||||
emit "bcctrl 20, 0, 0" \
|
||||
cost 8;
|
||||
|
||||
CALLINDIRECT(CALL)
|
||||
out:(iret)reg = CALLINDIRECT(CALL.I)
|
||||
out:(lret)reg = CALLINDIRECT(CALL.L)
|
||||
|
||||
JUMP(dest:LABEL.I)
|
||||
emit "b $dest"
|
||||
cost 4;
|
||||
|
||||
|
||||
|
||||
/* Comparisons */
|
||||
|
||||
cr:(cr)cr = COMPARESI.I(left:(int)reg, right:(int)reg)
|
||||
emit "cmp %cr, 0, %left, %right"
|
||||
cost 4;
|
||||
|
||||
cr:(cr)cr = COMPARESI.I(left:(int)reg, right:CONST.I)
|
||||
when signed_constant(%right, 16)
|
||||
emit "cmpi %cr, 0, %left, $right"
|
||||
cost 4;
|
||||
|
||||
cr:(cr)cr = COMPAREUI.I(left:(int)reg, right:(int)reg)
|
||||
emit "cmpl %cr, 0, %left, %right"
|
||||
cost 4;
|
||||
|
||||
cr:(cr)cr = COMPAREUI.I(left:(int)reg, right:CONST.I)
|
||||
when signed_constant(%right, 16)
|
||||
emit "cmpli %cr, 0, %left, $right"
|
||||
cost 4;
|
||||
|
||||
out:(cr)cr = COMPARESI.I(in:(cr)cr, result:CONST.I)
|
||||
when specific_constant(%result, 0)
|
||||
with %out == %in
|
||||
emit "! COMPARESI.I(cr, 0)"
|
||||
cost 4;
|
||||
|
||||
|
||||
|
||||
/* Booleans */
|
||||
|
||||
out:(int)reg = IFEQ.I(in:(cr)cr)
|
||||
emit "mfcr %out" /* get cr0 */
|
||||
emit "rlwinm %out, %out, [32-2], 2, 31" /* extract just EQ */
|
||||
cost 8;
|
||||
|
||||
out:(int)reg = IFEQ.I(in:(int)reg)
|
||||
emit "cntlzw %out, %in" /* returns 0..32 */
|
||||
emit "rlwinm %out, %out, [32-5], 5, 31" /* if 32, return 1, otherwise 0 */
|
||||
cost 8;
|
||||
|
||||
out:(int)reg = IFLT.I(in:(cr)cr)
|
||||
emit "mfcr %out" /* get cr0 */
|
||||
emit "andi. %out, %out, 1" /* leave just LT */
|
||||
cost 8;
|
||||
|
||||
out:(int)reg = IFLE.I(in:(cr)cr)
|
||||
emit "mfcr %out" /* get cr0 */
|
||||
emit "andi. %out, %out, 5" /* leave just LT and EQ */
|
||||
emit "cntlzw %out, %out" /* returns 0..32 */
|
||||
emit "rlwinm %out, %out, [32-5], 5, 31" /* if 32, return 1, otherwise 0 */
|
||||
emit "xori %out, %out, 1" /* negate */
|
||||
cost 8;
|
||||
|
||||
|
||||
|
||||
/* Conversions */
|
||||
|
||||
#if 0
|
||||
out:(int)reg = CIU44(in:(int)reg)
|
||||
with %out == %in
|
||||
emit "! ciu44"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = CUI44(in:(int)reg)
|
||||
with %out == %in
|
||||
emit "! cui44"
|
||||
cost 4;
|
||||
#endif
|
||||
|
||||
/* ALU operations */
|
||||
|
||||
#define ALUR(name, instr) \
|
||||
out:(int)reg = name(left:(int)reg, right:(int)reg) \
|
||||
emit instr " %out, %left, %right" \
|
||||
cost 4; \
|
||||
|
||||
#define ALUC(name, instr) \
|
||||
out:(int)reg = name(left:(int)reg, right:CONST.I) \
|
||||
when signed_constant(%right, 16) \
|
||||
emit instr " %out, %left, $right" \
|
||||
cost 4; \
|
||||
|
||||
#define ALUC_reversed(name, instr) \
|
||||
out:(int)reg = name(left:CONST.I, right:(int)reg) \
|
||||
when signed_constant(%left, 16) \
|
||||
emit instr " %out, %right, $left" \
|
||||
cost 4; \
|
||||
|
||||
#define ALUCC(name, instr) \
|
||||
ALUC(name, instr) \
|
||||
ALUC_reversed(name, instr)
|
||||
|
||||
ALUR(ADD.I, "add")
|
||||
ALUCC(ADD.I, "addi")
|
||||
|
||||
out:(int)reg = SUB.I(left:(int)reg, right:(int)reg)
|
||||
emit "subf %out, %right, %left"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = SUB.I(left:(int)reg, right:CONST.I)
|
||||
emit "addi %out, %left, -[$right]"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = MOD.I(left:(int)reg, right:(int)reg)
|
||||
with preserved(%left), preserved(%right)
|
||||
emit "divw %out, %left, %right"
|
||||
emit "mullw %out, %out, %right"
|
||||
emit "subf %out, %out, %left"
|
||||
cost 12;
|
||||
|
||||
out:(int)reg = MODU.I(left:(int)reg, right:(int)reg)
|
||||
with preserved(%left), preserved(%right)
|
||||
emit "divwu %out, %left, %right"
|
||||
emit "mullw %out, %out, %right"
|
||||
emit "subf %out, %out, %left"
|
||||
cost 12;
|
||||
|
||||
ALUR(MUL.I, "mullw")
|
||||
ALUCC(MUL.I, "mulli")
|
||||
|
||||
ALUR(DIV.I, "divw")
|
||||
ALUR(DIVU.I, "divwu")
|
||||
|
||||
ALUR(ASL.I, "slw")
|
||||
ALUR(ASR.I, "sraw")
|
||||
|
||||
ALUR(LSL.I, "slw")
|
||||
ALUR(LSR.I, "srw")
|
||||
|
||||
out:(int)reg = NEG.I(left:(int)reg)
|
||||
emit "neg %out, %left"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = NOT.I(left:(int)reg)
|
||||
emit "cntlzw %out, %left"
|
||||
emit "rlwinm %out, %out, 32-5, 5, 31"
|
||||
cost 8;
|
||||
|
||||
ALUR(AND.I, "and")
|
||||
ALUCC(AND.I, "andi.")
|
||||
|
||||
ALUR(OR.I, "or")
|
||||
ALUCC(OR.I, "ori")
|
||||
|
||||
ALUR(EOR.I, "xor")
|
||||
ALUCC(EOR.I, "xori")
|
||||
|
||||
out:(int)reg = value:LABEL.I
|
||||
emit "li32 %out, $value"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = value:BLOCK.I
|
||||
emit "li32 %out, $value"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = value:CONST.I
|
||||
emit "li32 %out, $value"
|
||||
cost 8;
|
||||
|
||||
|
||||
/* FPU operations */
|
||||
|
||||
#define FPU4R(name, instr) \
|
||||
out:(float)reg = name(left:(float)reg, right:(float)reg) \
|
||||
emit instr " %out, %left, %right" \
|
||||
cost 4; \
|
||||
|
||||
#define FPU8R(name, instr) \
|
||||
out:(double)reg = name(left:(double)reg, right:(double)reg) \
|
||||
emit instr " %out, %left, %right" \
|
||||
cost 4; \
|
||||
|
||||
out:(float)reg = LOAD.F(addr:address)
|
||||
emit "lfs %out, %addr"
|
||||
cost 4;
|
||||
|
||||
out:(double)reg = LOAD.D(addr:address)
|
||||
emit "lfd %out, %addr"
|
||||
cost 4;
|
||||
|
||||
out:(float)reg = in:CONST.F
|
||||
when specific_constant(%in, 0)
|
||||
emit "li32 r0, .fd_00000000"
|
||||
emit "lfs %out, 0(r0)"
|
||||
cost 12;
|
||||
|
||||
FPU4R(ADDF.F, "fadds")
|
||||
FPU8R(ADDF.D, "fadd")
|
||||
|
||||
FPU4R(SUBF.F, "fsubs")
|
||||
FPU8R(SUBF.D, "fsub")
|
||||
|
||||
FPU4R(MULF.F, "fmuls")
|
||||
FPU8R(MULF.D, "fmul")
|
||||
|
||||
FPU4R(DIVF.F, "fdivs")
|
||||
FPU8R(DIVF.D, "fdiv")
|
||||
|
||||
#define FMALEFT(type, insn, add, mul) \
|
||||
out:(type)reg = add(mul(m1:(type)reg, m2:(type)reg), m3:(type)reg) \
|
||||
emit insn " %out, %m1, %m2, %m3" \
|
||||
cost 4; \
|
||||
|
||||
#define FMARIGHT(type, insn, add, mul) \
|
||||
out:(type)reg = add(m3:(type)reg, mul(m1:(type)reg, m2:(type)reg)) \
|
||||
emit insn " %out, %m1, %m2, %m3" \
|
||||
cost 4; \
|
||||
|
||||
FMALEFT( double, "fmadd", ADDF.D, MULF.D)
|
||||
FMARIGHT(double, "fmadd", ADDF.D, MULF.D)
|
||||
FMALEFT( float, "fmadds", ADDF.F, MULF.F)
|
||||
FMARIGHT(float, "fmadds", ADDF.F, MULF.F)
|
||||
|
||||
FMALEFT( double, "fmsub", SUBF.D, MULF.D)
|
||||
FMALEFT( float, "fmsubs", SUBF.F, MULF.F)
|
||||
|
||||
FMARIGHT(double, "fnmadd", SUBF.D, MULF.D)
|
||||
FMARIGHT(float, "fnmadds", SUBF.F, MULF.F)
|
||||
|
||||
#define FMANEGLEFT(type, insn, neg, add, mul) \
|
||||
out:(type)reg = neg(add(mul(m1:(type)reg, m2:(type)reg), m3:(type)reg)) \
|
||||
emit insn " %out, %m1, %m2, %m3" \
|
||||
cost 4; \
|
||||
|
||||
#define FMANEGRIGHT(type, insn, neg, add, mul) \
|
||||
out:(type)reg = neg(add(m3:(type)reg, mul(m1:(type)reg, m2:(type)reg))) \
|
||||
emit insn " %out, %m1, %m2, %m3" \
|
||||
cost 4; \
|
||||
|
||||
FMANEGLEFT( double, "fnmsub", NEGF.D, ADDF.D, MULF.D)
|
||||
FMANEGRIGHT(double, "fnmsub", NEGF.D, ADDF.D, MULF.D)
|
||||
FMANEGLEFT( float, "fnmsub", NEGF.F, ADDF.F, MULF.F)
|
||||
FMANEGRIGHT(float, "fnmsub", NEGF.F, ADDF.F, MULF.F)
|
||||
|
||||
out:(float)reg = NEGF.F(left:(float)reg)
|
||||
emit "fneg %out, %left"
|
||||
cost 4;
|
||||
|
||||
out:(double)reg = NEGF.D(left:(double)reg)
|
||||
emit "fneg %out, %left"
|
||||
cost 4;
|
||||
|
||||
cr:(cr)cr = COMPAREF.I(left:(float)reg, right:(float)reg)
|
||||
emit "fcmpu %cr, %left, %right"
|
||||
cost 4;
|
||||
|
||||
cr:(cr)cr = COMPARED.I(left:(double)reg, right:(double)reg)
|
||||
emit "fcmpu %cr, %left, %right"
|
||||
cost 4;
|
||||
|
||||
/* vim: set sw=4 ts=4 expandtab : */
|
||||
|
|
@ -56,6 +56,7 @@ con_mult(word sz)
|
|||
#define FL_MSB_AT_LOW_ADDRESS 1
|
||||
#include <con_float>
|
||||
|
||||
void
|
||||
prolog(full nlocals)
|
||||
{
|
||||
int ss = nlocals + 8;
|
||||
|
@ -68,6 +69,7 @@ prolog(full nlocals)
|
|||
framesize = nlocals;
|
||||
}
|
||||
|
||||
void
|
||||
mes(word type)
|
||||
{
|
||||
int argt ;
|
||||
|
|
|
@ -328,6 +328,7 @@ INSTRUCTIONS
|
|||
lhax GPR:wo, GPR:ro, GPR:ro cost(4, 3).
|
||||
lhz GPR:wo, GPRINDIRECT:ro cost(4, 3).
|
||||
lhzx GPR:wo, GPR:ro, GPR:ro cost(4, 3).
|
||||
li32 GPR:wo, CONST:ro cost(8, 2).
|
||||
li32 GPR:wo, LABEL:ro cost(8, 2).
|
||||
lwzu GPR:wo, GPRINDIRECT:ro cost(4, 3).
|
||||
lwzx GPR:wo, GPR:ro, GPR:ro cost(4, 3).
|
||||
|
@ -1637,14 +1638,13 @@ PATTERNS
|
|||
gen
|
||||
bl {LABEL, ".set"}
|
||||
|
||||
pat inn defined($1) /* Test for set bit */
|
||||
leaving
|
||||
set INT32
|
||||
and INT32
|
||||
|
||||
pat inn !defined($1) /* Test for set bit (variable) */
|
||||
with GPR3 STACK
|
||||
pat inn /* Test for set bit */
|
||||
with STACK
|
||||
kills ALL
|
||||
uses REG
|
||||
gen
|
||||
li32 %a, {CONST, $1}
|
||||
stwu %a, {GPRINDIRECT, SP, 0-4}
|
||||
bl {LABEL, ".inn"}
|
||||
|
||||
|
||||
|
@ -1898,12 +1898,12 @@ PATTERNS
|
|||
addi SP, SP, {CONST, 12}
|
||||
|
||||
pat csa /* Array-lookup switch */
|
||||
with GPR3 GPR4 STACK
|
||||
with STACK
|
||||
gen
|
||||
b {LABEL, ".csa"}
|
||||
|
||||
pat csb /* Table-lookup switch */
|
||||
with GPR3 GPR4 STACK
|
||||
with STACK
|
||||
gen
|
||||
b {LABEL, ".csb"}
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
|
||||
/* 68020 desciptor table for ACK target optimizer */
|
||||
/* PowerPC desciptor table for ACK target optimizer */
|
||||
|
||||
MAXOP 3;
|
||||
LABEL_STARTER '.';
|
||||
|
||||
%%;
|
||||
|
||||
|
@ -15,6 +16,14 @@ X, Y, Z { TRUE };
|
|||
addi X, X, 0 -> ;
|
||||
addis X, X, 0 -> ;
|
||||
|
||||
mr X, X -> ;
|
||||
fmr X, X -> ;
|
||||
|
||||
or X, Y, Z : or. X, X, X -> or. X, Y, Z ;
|
||||
|
||||
b X : labdef X -> labdef X ;
|
||||
|
||||
/* IFFALSE=4, IFTRUE=12, ALWAYS=20 */
|
||||
/* LT=0, GT=1, EQ=2, OV=3 */
|
||||
|
||||
%%;
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
* All preprocessor based options/constants/functions
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* ========== ON/OFF options (use #define in mach0.c) ========== */
|
||||
|
||||
/*
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
void setupoutput();
|
||||
void commfinish();
|
||||
|
||||
/* ========== Machine independent C routines ========== */
|
||||
|
||||
void stop() {
|
||||
|
@ -458,6 +461,7 @@ char *s;
|
|||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
setupoutput()
|
||||
{
|
||||
register sect_t *sp;
|
||||
|
@ -493,6 +497,7 @@ setupoutput()
|
|||
outhead.oh_nchar = off; /* see newsymb() */
|
||||
}
|
||||
|
||||
void
|
||||
commfinish()
|
||||
{
|
||||
#ifndef ASLD
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
void putval();
|
||||
|
||||
yylex()
|
||||
{
|
||||
register c;
|
||||
|
@ -68,6 +70,7 @@ yylex()
|
|||
return(c);
|
||||
}
|
||||
|
||||
void
|
||||
putval(c)
|
||||
{
|
||||
register valu_t v;
|
||||
|
|
|
@ -12,6 +12,10 @@
|
|||
#include "comm1.h"
|
||||
#include "y.tab.h"
|
||||
|
||||
void switchsect();
|
||||
void newsymb();
|
||||
void newident();
|
||||
|
||||
newequate(ip, typ)
|
||||
register item_t *ip;
|
||||
register int typ;
|
||||
|
@ -34,6 +38,7 @@ register int typ;
|
|||
newident(ip, typ);
|
||||
}
|
||||
|
||||
void
|
||||
newident(ip, typ)
|
||||
register item_t *ip;
|
||||
{
|
||||
|
@ -74,6 +79,7 @@ register item_t *ip;
|
|||
);
|
||||
}
|
||||
|
||||
void
|
||||
newlabel(ip)
|
||||
register item_t *ip;
|
||||
{
|
||||
|
@ -183,6 +189,7 @@ valu_t val;
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
switchsect(newtyp)
|
||||
int newtyp;
|
||||
{
|
||||
|
@ -242,6 +249,7 @@ valu_t bytes;
|
|||
}
|
||||
|
||||
#ifdef RELOCATION
|
||||
void
|
||||
newrelo(s, n)
|
||||
{
|
||||
int iscomm;
|
||||
|
@ -326,6 +334,7 @@ new_string(s)
|
|||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
newsymb(name, type, desc, valu)
|
||||
register char *name;
|
||||
valu_t valu;
|
||||
|
|
42
mach/proto/mcg/basicblock.c
Normal file
42
mach/proto/mcg/basicblock.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
#include "mcg.h"
|
||||
|
||||
static void init_idf();
|
||||
static struct idf* str2idf(char* tg, int cp);
|
||||
|
||||
#define IDF_TYPE struct basicblock*
|
||||
#define IDF_NAME block
|
||||
#include <idf_pkg.spec>
|
||||
#include <idf_pkg.body>
|
||||
|
||||
static int next_id = 0;
|
||||
|
||||
void bb_init(void)
|
||||
{
|
||||
init_idf();
|
||||
}
|
||||
|
||||
struct basicblock* bb_get(const char* name)
|
||||
{
|
||||
struct idf* p;
|
||||
|
||||
if (!name)
|
||||
name = aprintf(".anon_bb_%d", next_id++);
|
||||
p = str2idf((char*) name, 0);
|
||||
if (!p->block)
|
||||
{
|
||||
p->block = calloc(1, sizeof(*p->block));
|
||||
p->block->name = name;
|
||||
}
|
||||
return p->block;
|
||||
}
|
||||
|
||||
void bb_alias(struct basicblock* block, const char* name)
|
||||
{
|
||||
struct idf* p = str2idf((char*) name, -1);
|
||||
assert(p == NULL);
|
||||
|
||||
p = str2idf((char*) name, 0);
|
||||
p->block = block;
|
||||
}
|
||||
|
||||
/* vim: set sw=4 ts=4 expandtab : */
|
43
mach/proto/mcg/basicblock.h
Normal file
43
mach/proto/mcg/basicblock.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
#ifndef BASICBLOCK_H
|
||||
#define BASICBLOCK_H
|
||||
|
||||
struct phi
|
||||
{
|
||||
struct basicblock* prev; /* Predecessor that this phi is referring to */
|
||||
struct ir* ir; /* IR of variable definition */
|
||||
};
|
||||
|
||||
struct basicblock
|
||||
{
|
||||
const char* name;
|
||||
ARRAYOF(struct em) ems;
|
||||
ARRAYOF(struct ir) irs;
|
||||
ARRAYOF(struct hop) hops;
|
||||
|
||||
ARRAYOF(struct basicblock) prevs;
|
||||
ARRAYOF(struct basicblock) nexts;
|
||||
int order; /* used by dominance graph code */
|
||||
|
||||
PMAPOF(struct vreg, struct phi) phis;
|
||||
|
||||
/* Used by liveness calculation. */
|
||||
ARRAYOF(struct vreg) liveins;
|
||||
ARRAYOF(struct vreg) liveouts;
|
||||
|
||||
/* Register assignments on entry and exit. */
|
||||
register_assignment_t regsin;
|
||||
register_assignment_t* regsout; /* points at regsout of the last insn. */
|
||||
|
||||
bool is_fake : 1;
|
||||
bool is_root : 1;
|
||||
bool is_terminated : 1;
|
||||
};
|
||||
|
||||
extern void bb_init(void);
|
||||
extern struct basicblock* bb_get(const char* name);
|
||||
extern void bb_alias(struct basicblock* block, const char* name);
|
||||
|
||||
#endif
|
||||
|
||||
/* vim: set sw=4 ts=4 expandtab : */
|
||||
|
51
mach/proto/mcg/build.lua
Normal file
51
mach/proto/mcg/build.lua
Normal file
|
@ -0,0 +1,51 @@
|
|||
include("util/mcgg/build.lua")
|
||||
|
||||
definerule("build_mcg",
|
||||
{
|
||||
arch = { type="string" }
|
||||
},
|
||||
function(e)
|
||||
-- Remember this is executed from the caller's directory; local
|
||||
-- target names will resolve there
|
||||
local headers = clibrary {
|
||||
name = e.name.."/headers",
|
||||
srcs = {},
|
||||
hdrs = {
|
||||
"mach/proto/mcg/*.h",
|
||||
"mach/"..e.arch.."/mcg/*.h",
|
||||
}
|
||||
}
|
||||
|
||||
local tables = mcgg {
|
||||
name = e.name.."/tables",
|
||||
srcs = { "mach/"..e.arch.."/mcg/table" }
|
||||
}
|
||||
|
||||
return cprogram {
|
||||
name = e.name,
|
||||
srcs = {
|
||||
"mach/proto/mcg/*.c",
|
||||
"mach/"..e.arch.."/mcg/platform.c",
|
||||
matching(filenamesof(tables), "%.c$")
|
||||
},
|
||||
deps = {
|
||||
"h+emheaders",
|
||||
"modules+headers",
|
||||
"modules/src/alloc+lib",
|
||||
"modules/src/data+lib",
|
||||
"modules/src/em_code+lib_k",
|
||||
"modules/src/em_data+lib",
|
||||
"modules/src/flt_arith+lib",
|
||||
"modules/src/idf+lib",
|
||||
"modules/src/object+lib",
|
||||
"modules/src/read_em+lib_kv",
|
||||
"modules/src/string+lib",
|
||||
"modules/src/system+lib",
|
||||
"util/mcgg+lib",
|
||||
headers,
|
||||
tables, -- for .h file
|
||||
}
|
||||
}
|
||||
end
|
||||
)
|
||||
|
160
mach/proto/mcg/data.c
Normal file
160
mach/proto/mcg/data.c
Normal file
|
@ -0,0 +1,160 @@
|
|||
#include "mcg.h"
|
||||
#include <ctype.h>
|
||||
|
||||
#define IEEEFLOAT
|
||||
#define FL_MSL_AT_LOW_ADDRESS 1
|
||||
#define FL_MSW_AT_LOW_ADDRESS 1
|
||||
#define FL_MSB_AT_LOW_ADDRESS 1
|
||||
|
||||
#include "con_float"
|
||||
|
||||
static struct symbol* pending;
|
||||
|
||||
void data_label(const char* label)
|
||||
{
|
||||
if (pending)
|
||||
fatal("two consecutive data labels ('%s' and '%s')",
|
||||
pending->name, label);
|
||||
|
||||
pending = symbol_get(label);
|
||||
if (pending->is_defined)
|
||||
fatal("label '%s' defined twice", pending->name);
|
||||
pending->is_defined = true;
|
||||
}
|
||||
|
||||
static const char* section_to_str(int section)
|
||||
{
|
||||
switch (section)
|
||||
{
|
||||
case SECTION_ROM: return ".rom";
|
||||
case SECTION_DATA: return ".data";
|
||||
case SECTION_BSS: return ".bss";
|
||||
case SECTION_TEXT: return ".text";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_header(int desired_section)
|
||||
{
|
||||
if (pending)
|
||||
{
|
||||
if (pending->section == SECTION_UNKNOWN)
|
||||
pending->section = desired_section;
|
||||
else if (pending->section != desired_section)
|
||||
fatal("label '%s' can't change sections", pending->name);
|
||||
|
||||
fprintf(outputfile, "\n.sect %s\n", section_to_str(pending->section));
|
||||
fprintf(outputfile, "%s:\n", platform_label(pending->name));
|
||||
pending = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void writehex(arith data, int size)
|
||||
{
|
||||
if (data < 0)
|
||||
fprintf(outputfile, "-0x%0*lx", size*2, -data);
|
||||
else
|
||||
fprintf(outputfile, "0x%0*lx", size*2, data);
|
||||
}
|
||||
|
||||
void data_int(arith data, size_t size, bool is_ro)
|
||||
{
|
||||
emit_header(is_ro ? SECTION_ROM : SECTION_DATA);
|
||||
assert((size == 1) || (size == 2) || (size == 4) || (size == 8));
|
||||
fprintf(outputfile, "\t.data%d ", size);
|
||||
writehex(data, size);
|
||||
fprintf(outputfile, "\n");
|
||||
}
|
||||
|
||||
|
||||
void data_float(const char* data, size_t size, bool is_ro)
|
||||
{
|
||||
unsigned char buffer[8];
|
||||
int i;
|
||||
|
||||
emit_header(is_ro ? SECTION_ROM : SECTION_DATA);
|
||||
assert((size == 4) || (size == 8));
|
||||
|
||||
i = float_cst(data, size, (char*) buffer);
|
||||
if ((i != 0) && (i != 2)) /* 2 == overflow */
|
||||
fatal("cannot parse floating point constant %s sz %d", data, size);
|
||||
|
||||
fprintf(outputfile, "\t!float %s sz %d\n", data, size);
|
||||
fprintf(outputfile, "\t.data1 ");
|
||||
writehex(buffer[0], 1);
|
||||
for (i=1; i<size; i++)
|
||||
{
|
||||
fprintf(outputfile, ", ");
|
||||
writehex(buffer[i], 1);
|
||||
}
|
||||
fprintf(outputfile, "\n");
|
||||
}
|
||||
|
||||
static bool istext(c)
|
||||
{
|
||||
return isprint(c) && (c != '"');
|
||||
}
|
||||
|
||||
void data_block(const uint8_t* data, size_t size, bool is_ro)
|
||||
{
|
||||
const uint8_t* start = data;
|
||||
const uint8_t* end = data + size;
|
||||
const uint8_t* p = data;
|
||||
|
||||
emit_header(is_ro ? SECTION_ROM : SECTION_DATA);
|
||||
|
||||
start = p = data;
|
||||
while (p < end)
|
||||
{
|
||||
while ((p < end) && istext(*p))
|
||||
p++;
|
||||
|
||||
if (start < p)
|
||||
{
|
||||
fprintf(outputfile, "\t.ascii \"");
|
||||
while (start < p)
|
||||
{
|
||||
fprintf(outputfile, "%c", *start);
|
||||
start++;
|
||||
}
|
||||
fprintf(outputfile, "\"\n");
|
||||
}
|
||||
|
||||
while ((p < end) && !istext(*p))
|
||||
p++;
|
||||
|
||||
if (start < p)
|
||||
{
|
||||
bool first = true;
|
||||
|
||||
fprintf(outputfile, "\t.data1 ");
|
||||
while (start < p)
|
||||
{
|
||||
if (!first)
|
||||
fprintf(outputfile, ", ");
|
||||
writehex(*start, 1);
|
||||
start++;
|
||||
first = false;
|
||||
}
|
||||
fprintf(outputfile, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void data_offset(const char* label, arith offset, bool is_ro)
|
||||
{
|
||||
emit_header(is_ro ? SECTION_ROM : SECTION_DATA);
|
||||
fprintf(outputfile, "\t.data%d %s+%lld\n",
|
||||
EM_pointersize, platform_label(label), offset);
|
||||
}
|
||||
|
||||
void data_bss(arith size, int init)
|
||||
{
|
||||
if (init != 0)
|
||||
fatal("non-zero-initialised bss not supported");
|
||||
|
||||
emit_header(SECTION_BSS);
|
||||
fprintf(outputfile, "\t.space %lld\n", size);
|
||||
}
|
||||
|
||||
/* vim: set sw=4 ts=4 expandtab : */
|
210
mach/proto/mcg/graph.c
Normal file
210
mach/proto/mcg/graph.c
Normal file
|
@ -0,0 +1,210 @@
|
|||
#include "mcg.h"
|
||||
|
||||
struct graph_data cfg;
|
||||
struct dominance_data dominance;
|
||||
|
||||
static ARRAYOF(struct basicblock) pending;
|
||||
|
||||
static bool collect_outputs_cb(struct ir* ir, void* user)
|
||||
{
|
||||
struct basicblock* caller = user;
|
||||
|
||||
if (ir->opcode == IR_BLOCK)
|
||||
{
|
||||
array_appendu(&caller->nexts, ir->u.bvalue);
|
||||
array_appendu(&ir->u.bvalue->prevs, caller);
|
||||
pmap_add(&cfg.graph, caller, ir->u.bvalue);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void update_block_pointers_from_ir(void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i=0; i<current_proc->blocks.count; i++)
|
||||
{
|
||||
struct basicblock* bb = current_proc->blocks.item[i];
|
||||
bb->prevs.count = bb->nexts.count = 0;
|
||||
}
|
||||
|
||||
for (i=0; i<current_proc->blocks.count; i++)
|
||||
{
|
||||
struct basicblock* bb = current_proc->blocks.item[i];
|
||||
for (j=0; j<bb->irs.count; j++)
|
||||
ir_walk(bb->irs.item[j], collect_outputs_cb, bb);
|
||||
}
|
||||
|
||||
for (i=0; i<current_proc->blocks.count; i++)
|
||||
{
|
||||
struct basicblock* bb = current_proc->blocks.item[i];
|
||||
|
||||
for (j=0; j<bb->nexts.count; j++)
|
||||
{
|
||||
tracef('D', "D: cfg graph %s -> %s\n",
|
||||
bb->name,
|
||||
bb->nexts.item[j]->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void recursively_walk_cfg_graph(struct basicblock* bb)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (array_contains(&cfg.postorder, bb) || array_contains(&pending, bb))
|
||||
return;
|
||||
|
||||
array_appendu(&cfg.preorder, bb);
|
||||
array_appendu(&pending, bb);
|
||||
|
||||
for (i=0; i<bb->nexts.count; i++)
|
||||
recursively_walk_cfg_graph(bb->nexts.item[i]);
|
||||
|
||||
array_remove(&pending, bb);
|
||||
bb->order = cfg.postorder.count;
|
||||
array_appendu(&cfg.postorder, bb);
|
||||
}
|
||||
|
||||
static void walk_cfg_graph(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
cfg.preorder.count = 0;
|
||||
cfg.postorder.count = 0;
|
||||
pending.count = 0;
|
||||
recursively_walk_cfg_graph(cfg.entry);
|
||||
|
||||
for (i=0; i<cfg.preorder.count; i++)
|
||||
{
|
||||
tracef('G', "G: cfg preorder: %s\n",
|
||||
cfg.preorder.item[i]->name);
|
||||
}
|
||||
}
|
||||
|
||||
static struct basicblock* intersect(struct basicblock* p1, struct basicblock* p2)
|
||||
{
|
||||
while (p1 != p2)
|
||||
{
|
||||
while (p1->order < p2->order)
|
||||
p1 = pmap_findleft(&dominance.graph, p1);
|
||||
|
||||
while (p2->order < p1->order)
|
||||
p2 = pmap_findleft(&dominance.graph, p2);
|
||||
}
|
||||
|
||||
return p1;
|
||||
}
|
||||
|
||||
static void calculate_dominance_graph(void)
|
||||
{
|
||||
/* This is the algorithm described here:
|
||||
*
|
||||
* Cooper, Keith D., Timothy J. Harvey, and Ken Kennedy.
|
||||
* "A simple, fast dominance algorithm."
|
||||
* Software Practice & Experience 4.1-10 (2001): 1-8.
|
||||
*
|
||||
* https://www.cs.rice.edu/~keith/EMBED/dom.pdf
|
||||
*/
|
||||
|
||||
int i, j;
|
||||
bool changed;
|
||||
|
||||
dominance.graph.count = 0;
|
||||
|
||||
/* The entry block dominates itself. */
|
||||
|
||||
pmap_put(&dominance.graph, cfg.entry, cfg.entry);
|
||||
|
||||
do
|
||||
{
|
||||
changed = false;
|
||||
|
||||
for (i = cfg.postorder.count-2; i >= 0; i--)
|
||||
{
|
||||
struct basicblock* b = cfg.postorder.item[i];
|
||||
struct basicblock* new_idom = NULL;
|
||||
for (j=0; j<b->prevs.count; j++)
|
||||
{
|
||||
struct basicblock* p = b->prevs.item[j];
|
||||
|
||||
/* Skip unprocessed blocks. */
|
||||
if (!pmap_findleft(&dominance.graph, p))
|
||||
continue;
|
||||
|
||||
if (!new_idom)
|
||||
new_idom = p;
|
||||
else if (pmap_findleft(&dominance.graph, p))
|
||||
new_idom = intersect(p, new_idom);
|
||||
}
|
||||
|
||||
if (pmap_findleft(&dominance.graph, b) != new_idom)
|
||||
{
|
||||
pmap_put(&dominance.graph, b, new_idom);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (changed);
|
||||
|
||||
for (i=0; i<dominance.graph.count; i++)
|
||||
{
|
||||
tracef('G', "G: dominance graph: %s -> %s\n",
|
||||
dominance.graph.item[i].right->name,
|
||||
dominance.graph.item[i].left->name);
|
||||
}
|
||||
}
|
||||
|
||||
static void recursively_walk_dominance_graph(struct basicblock* bb)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (array_contains(&dominance.postorder, bb) || array_contains(&pending, bb))
|
||||
return;
|
||||
|
||||
array_appendu(&dominance.preorder, bb);
|
||||
array_appendu(&pending, bb);
|
||||
|
||||
for (i=0; i<dominance.graph.count; i++)
|
||||
if (dominance.graph.item[i].right == bb)
|
||||
recursively_walk_dominance_graph(dominance.graph.item[i].left);
|
||||
|
||||
array_remove(&pending, bb);
|
||||
array_appendu(&dominance.postorder, bb);
|
||||
}
|
||||
|
||||
static void walk_dominance_graph(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
dominance.preorder.count = 0;
|
||||
dominance.postorder.count = 0;
|
||||
pending.count = 0;
|
||||
recursively_walk_dominance_graph(cfg.entry);
|
||||
|
||||
for (i=0; i<dominance.preorder.count; i++)
|
||||
{
|
||||
tracef('G', "G: dominance preorder: %s\n",
|
||||
dominance.preorder.item[i]->name);
|
||||
}
|
||||
}
|
||||
|
||||
void update_graph_data(void)
|
||||
{
|
||||
cfg.entry = current_proc->blocks.item[0];
|
||||
cfg.graph.count = 0;
|
||||
update_block_pointers_from_ir();
|
||||
|
||||
walk_cfg_graph();
|
||||
assert(cfg.postorder.count == current_proc->blocks.count);
|
||||
assert(cfg.preorder.count == current_proc->blocks.count);
|
||||
|
||||
calculate_dominance_graph();
|
||||
|
||||
walk_dominance_graph();
|
||||
assert(dominance.postorder.count == dominance.graph.count);
|
||||
assert(dominance.preorder.count == dominance.graph.count);
|
||||
}
|
||||
|
||||
/* vim: set sw=4 ts=4 expandtab : */
|
||||
|
27
mach/proto/mcg/graph.h
Normal file
27
mach/proto/mcg/graph.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef GRAPH_H
|
||||
#define GRAPH_H
|
||||
|
||||
struct graph_data
|
||||
{
|
||||
struct basicblock* entry;
|
||||
PMAPOF(struct basicblock, struct basicblock) graph;
|
||||
ARRAYOF(struct basicblock) preorder;
|
||||
ARRAYOF(struct basicblock) postorder;
|
||||
};
|
||||
|
||||
struct dominance_data
|
||||
{
|
||||
PMAPOF(struct basicblock, struct basicblock) graph;
|
||||
ARRAYOF(struct basicblock) preorder;
|
||||
ARRAYOF(struct basicblock) postorder;
|
||||
};
|
||||
|
||||
extern struct graph_data cfg;
|
||||
extern struct dominance_data dominance;
|
||||
|
||||
extern void update_graph_data(void);
|
||||
|
||||
#endif
|
||||
|
||||
/* vim: set sw=4 ts=4 expandtab : */
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue