⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdoc3

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻
📖 第 1 页 / 共 2 页
字号:
arranges that the current register is odd;the R\- notation allows the code to refer to the next lower,even-numbered register..LPTo refer to addressible quantities, there are the notations:.IP A1causes generation of the address specified by the first operand.For this to be legal, the operand must be addressible; its key must contain an `a'or a more restrictive specification..RT.IP A2correspondingly generates the address of the second operandproviding it has one..PPWe now have enough mechanism to show a complete, if suboptimal,table for the + operator on word or byte operands..DS%n,z	F.sp 1%n,1	F	inc	R.sp 1%n,aw	F	add	A2,R.sp 1%n,e	F	S1	add	R1,R.sp 1%n,n	SS	F	add	(sp)+,R.DEThe first two sequences handle some special cases.Actually it turns out that handling a right operand of 0is unnecessary since the expression-optimizerthrows out adds of 0.Adding 1 by using the `increment' instruction is done next,and then the case where the right operand is addressible.It must be a word quantity, since the PDP-11 lacks an `add byte' instruction.Finally the cases where the right operand either can, or cannot,be done in the available registers are treated..PPThe next macro-instructions are convenientlyintroduced by noticing that the above table is suitablefor subtraction as well as addition, since no use is made of thecommutativity of addition.All that is needed is substitution of `sub' for `add'and `dec' for 'inc.'Considerable saving of space is achieved by factoring outseveral similar operations..IP Iis replaced by a string from another table indexed by the operatorin the node being expanded.This secondary table actually contains two strings per operator..RT.IP I\(fmis replaced by the second string in the side tableentry for the current operator..PPThus, given that the entries for `+' and `\-' in the side table(which is called.II instab)are `add' and `inc,' `sub' and `dec'respectively,the middle of of the above addition table can be written.DS%n,1	F	I'	R%n,aw	F	I	A2,R.DEand it will be suitable for subtraction,and several other operators, as well..PPNext, there is the question of character and floating-point operations..IP B1generates the letter `b' if the first operand is a character,`f' if it is float or double, and nothing otherwise.It is used in a context like `movB1'which generates a `mov', `movb', or `movf'instruction according to the type of the operand..RT.IP B2is just like B1 but applies to the second operand..RT.IP BEgenerates `b' if either operand is a characterand null otherwise..RT.IP BFgenerates `f' if the type of the operator node itself is float or double,otherwise null..PPFor example, there is an entry in.II efftabfor the `=' operator.DS%a,aw%ab,a	IBE	A2,A1.DENote first that two key specificationscan be applied to the same code string.Next, observe that when a word is assigned to a byte or to a word,or a word is assigned to a byte,a single instruction,a.II movor.II movbas appropriate, does the job.However, when a byte is assigned to a word,it must pass through a register to implement the sign-extension rules:.DS%a,n	S	IB1	R,A1.DE.PPNext, there is the question of handling indirection properly.Consider the expression `X + *Y', where X and Y are expressions,Assuming that Y is more complicated than just a variable,but on the other hand qualifies as `easy' in the context,the expression would be compiled by placing the value of X in a register,that of *Y in the next register, and adding the registers.It is easy to see that a better job can be doneby compiling X, then Y (into the next register),and producing theinstruction symbolized by `add (R1),R'.This scheme avoids generatingthe instruction `mov (R1),R1'required actually to place the value of *Y in a register.A related situation occurswith the expression `X + *(p+6)', whichexemplifies a constructionfrequent in structure and array references.The addition table shown above would produce.DS[put X in register R]mov	p,R1add	$6,R1mov	(R1),R1add	R1,R.DEwhen the best code is.DS[put X in R]mov	p,R1add	6(R1),R.DEAs we said above, a key specification for a code table entrymay require an operand to have an indirection as its highest operator.To make use of the requirement,the following macros are provided..IP F*the first operand must have the form *X.If in particular it has the form *(Y + c), for some constant.II c,then code is produced which places the value of Y inthe current register.Otherwise, code is produced which loads X into the current register..RT.IP F1*resembles F* except that the next register is loaded..RT.IP S*resembles F* except that the second operand is loaded..RT.IP S1*resembles S* except that the next register is loaded..RT.IP FS*The first operand must have the form `*X'.Push the value of X on the stack..RT.IP SS*resembles FS* except that it applies to the second operand..LPTo capture the constant that may have been skipped overin the above macros, there are.IP #1The first operand must have the form *X;if in particular it has the form *(Y + c) for.II ca constant, then the constant is written out,otherwise a null string..RT.IP #2is the same as #1 except that the second operand is used..LPNow we can improve the addition table above.Just before the `%n,e' entry, put.DS%n,ew*	F	S1*	add	#2(R1),R.DEand just before the `%n,n' put.DS%n,nw*	SS*	F	add	*(sp)+,R.DEWhen using the stacking macros there is no place to usethe constantas an index word, so that particular special case doesn't occur..PPThe constant mentioned above can actually be moregeneral than a number.Any quantity acceptable to the assembler as an expression will do,in particular the address of a static cell, perhaps with a numeric offset.If.II xis an external character array,the expression `x[i+5] = 0' will generatethe code.DSmov	i,r0clrb	x+5(r0).DEvia the table entry (in the `=' part of.II efftab).DS%e*,z	F	I'B1	#1(R).DESome machine operations place restrictions on the registersused.The divide instruction, used to implement the divide and modoperations, requires the dividend to be placed in the odd memberof an even-odd pair;other peculiaritiesof multiplication make it simplest to put the multiplicandin an odd-numbered register.There is no theory which optimally accounts forthis kind of requirement..II Cexprhandles it by checking for a multiply, divide, or mod operation;in these cases, its argument register number is incremented byone or two so that it is odd, and if the operation was divide or mod,so that it is a member of a free even-odd pair.The routine which determines the number of registers requiredestimates, conservatively, thatat least two registers are required for a multiplicationand three for the other peculiar operators.After the expression is compiled,the register where the result actually ended up is returned.(Divide and mod are actually the same operation except for thelocation of the result)..PPThese operations are the ones which cause results to end up inunexpected places,and this possibility adds a further level of complexity.The simplest way of handling the problem is always to move theresult to the place where the caller expected it,but this will produce unnecessary register moves in manysimple cases; `a = b*c' would generate.DSmov	b,r1mul	c,r1mov	r1,r0mov	r0,a.DEThe next thought is used the passed-backinformation as to where the result landed to change the notion of the currentregister.While compiling the `=' operation above, which comes from atableentrylike.DS%a,e	S	mov	R,A1.DEit is sufficient to redefine the meaning of `R'after processing the `S' which does the multiply.This technique is in fact used; the tables are written in such a waythat correct code is produced.The trouble is that the technique cannot be used in general,because it invalidates the count of the number of registersrequired for an expression.Consider just `a*b + X' where X is some expression.The algorithm assumes that the value of a*b,once computed, requires just one register.If there are three registers available, and X requires two registers tocompute, then this expression will match a key specifying`%n,e'.If a*b is computed and left in register 1, then there are, contraryto expectations, no longer two registers available to compute X,but only one, and bad code will be produced.To guard against this possibility,.II cexprchecks the result returned by recursive calls which implementF, S and their relatives.If the result is not in the expected register, then the number ofregisters required by the other operand is checked;if it can be done using those registers which remain evenafter making unavailable the unexpectedly-occupiedregister, thenthe notions of the `next register' and possibly the `currentregister' are redefined.Otherwise a register-copy instruction is produced.A register-copy is also always producedwhen the current operator is one of those which have odd-even requirements..PPFinally, there are a few loose-end macro operationsand facts about the tables.The operators:.IP Vis used for long operations.It is written with an address like a machine instruction;it expands into `adc' (add carry) if the operationis an additive operator,`sbc' (subtract carry) if the operation is a subtractiveoperator, and disappears, along with the rest of the line, otherwise.Its purpose is to allow common treatment of logicaloperations, which have no carries, and additive and subtractiveoperations, which generate carries..RT.IP Tgenerates a `tst' instruction if the first operandof the tree does not set the condition codes correctly.It is used with divide and mod operations,which require a sign-extended 32-bit operand.The code table for the operations contains an `sxt'(sign-extend) instruction to generate the high-order part of thedividend..RT.IP His analogous to the `F' and `S' macros,except that it calls for the generation of code forthe current tree(not one of its operands)using.II regtab.It is used in.II cctabfor all the operators which, when executed normally,set the condition codes properly according to the result.It prevents a `tst' instruction from being generated forconstructions like `if (a+b) ...'since after calculation of the value of`a+b' a conditional branch can be written immediately..PPAll of the discussion above is in terms of operators with operands.Leaves of the expression tree (variables and constants), however,are peculiar in that they have no operands.In order to regularize the matching process,.II cexprexamines its operand to determine if it is a leaf;if so, it creates a special `load' operator whose operandis the leaf, and substitutes it for the argument tree;this allows the table entry for the created operatorto use the `A1' notation to load the leaf into a register..PPPurely to save space in the tables,pieces of subtables can be labelled and referred to later.It turns out, for example,that rather large portions of thethe.II efftabtable for the `=' and `=+' operators are identical.Thus `=' has an entry.DS%[move3:]%a,aw%ab,a	IBE	A2,A1.DEwhile part of the `=+' table is.DS%aw,aw%	[move3].DELabels are written as `%[ ... : ]',before the key specifications;referencesare writtenwith `%  [ ... ]'after the key.Peculiarities in the implementationmake it necessary that labels appear before references to them..PPThe example illustrates the utilityof allowing separate keysto point to the same code string.The assignment codeworks properly if either the right operand is a word, or the left operandis a byte;but since there is no `add byte' instruction the addition codehas to be restricted to word operands.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -